Skip to content

GH-110829: Ensure Thread.join() joins the OS thread#110848

Merged
pitrou merged 19 commits into
python:mainfrom
pitrou:gh-110829-join
Nov 4, 2023
Merged

GH-110829: Ensure Thread.join() joins the OS thread#110848
pitrou merged 19 commits into
python:mainfrom
pitrou:gh-110829-join

Conversation

@pitrou

@pitrou pitrou commented Oct 13, 2023

Copy link
Copy Markdown
Member

@pitrou

pitrou commented Oct 13, 2023

Copy link
Copy Markdown
Member Author

@gpshead This should work at least on Linux, hopefully on Windows if I'm lucky.

@pitrou pitrou force-pushed the gh-110829-join branch 2 times, most recently from ef411ef to 41b9cba Compare October 13, 2023 23:23
@pitrou pitrou added type-feature A feature request or enhancement 🔨 test-with-buildbots Test PR w/ buildbots; report in status section interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Oct 14, 2023
@bedevere-bot

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @pitrou for commit 6c594ce 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 14, 2023
@pitrou pitrou marked this pull request as ready for review October 14, 2023 07:47
@pitrou pitrou requested a review from gpshead October 14, 2023 07:47
@pitrou

pitrou commented Oct 14, 2023

Copy link
Copy Markdown
Member Author

@zooba I think my use of the Windows APIs is correct here, but you might want to take a look.

Comment thread Modules/_threadmodule.c Outdated
Comment on lines +55 to +59
unsigned long long ull_handle = PyLong_AsUnsignedLongLong(handle_obj);
if ((*ident == (unsigned long) -1 || ull_handle == (unsigned long long) -1)
&& PyErr_Occurred()) {
// This should not occur as we control the contents of state->joinable_dict
return -1;
}
*handle = (Py_uintptr_t) ull_handle;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed #110863 to ease this a bit.


def test_terminate(self):
if self.TYPE == 'threads':
self.skipTest("Threads cannot be terminated")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note the changes in this file are probably not necessary, it's just that without them the threads emulation of processes takes a very long time to test. The reason is simple and not related to this PR: while you can terminate a process early, you cannot do that on a thread, so joining a sleeping thread has to wait for the sleep to finish.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use a shorter wait time rather than skip the test entirely: #114186

Comment thread Modules/_threadmodule.c Outdated
} else {
PyThread_detach_thread((Py_uintptr_t) handle);
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might also want to emit a ResourceWarning here, what do you think @vstinner ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it, I'd rather defer this to a later PR (if at all).

Comment thread Include/pythread.h Outdated
@pitrou

pitrou commented Oct 14, 2023

Copy link
Copy Markdown
Member Author

!buildbot wasm

@bedevere-bot

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @pitrou for commit 26e868c 🤖

The command will test the builders whose names match following regular expression: wasm

The builders matched are:

  • wasm32-emscripten browser (dynamic linking, no tests) PR
  • wasm32-emscripten node (pthreads) PR
  • wasm32-emscripten node (dynamic linking) PR
  • wasm32-wasi PR

@pitrou

pitrou commented Oct 14, 2023

Copy link
Copy Markdown
Member Author

Most buildbots are green and the few failures look unrelated:
https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F110848%2Fmerge

Comment thread Python/thread_nt.h
@pitrou pitrou added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 16, 2023
@bedevere-bot

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @pitrou for commit e2f440f 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 16, 2023
@pitrou

pitrou commented Oct 17, 2023

Copy link
Copy Markdown
Member Author

I formally announce that there are no buildbot failures :-)

I realize that this PR lacks some docs for the _thread additions, but before that I would like someone to vet the overall approach. @gpshead Are you available for a review?

@gpshead

gpshead commented Oct 25, 2023

Copy link
Copy Markdown
Member

@gpshead Are you available for a review?

I'll take a look this week, I was on vacation.

@gpshead gpshead self-assigned this Oct 25, 2023
@pitrou pitrou added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Nov 4, 2023
@bedevere-bot

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @pitrou for commit 5cf2684 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Nov 4, 2023
@pitrou pitrou enabled auto-merge (squash) November 4, 2023 13:46
@pitrou pitrou merged commit 0e9c364 into python:main Nov 4, 2023
@pitrou pitrou deleted the gh-110829-join branch November 4, 2023 14:14
@pitrou

pitrou commented Nov 4, 2023

Copy link
Copy Markdown
Member Author

In an ironic (and depressing) twist, it seems that even after pthread_join returned successfully, the given thread can still appear in /proc/self/task. Forking should be safe in such a situation, but our fork() wrapper prints a warning nevertheless....

@gpshead

gpshead commented Nov 4, 2023

Copy link
Copy Markdown
Member

doh! I guess I can understand why, the thread won't be executing anymore so join succeeded but the in kernel data structure cleanup will take its own sweet time. :/

I still think it is a valuable addition that we wait for the OS join to happen (thanks for all this work, reviews & merge) but I understand it is annoying given one of the motivating reasons.

@rafa-rrayes rafa-rrayes left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants