bpo-39877: take_gil() now exits the thread if finalizing by vstinner · Pull Request #18854 · python/cpython (original) (raw)

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation12 Commits2 Checks0 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

vstinner

take_gil() is now responsible to exit the thread if Python is
finalizing. Not only exit before trying to acquire the GIL, but exit
also once the GIL is succesfully acquired.

https://bugs.python.org/issue39877

@vstinner

take_gil() is now responsible to exit the thread if Python is finalizing. Not only exit before trying to acquire the GIL, but exit also once the GIL is succesfully acquired.

@vstinner

@vstinner

I tested manually: with this change and PR #18848, asyncio_gc.py of bpo-19466 does no longer crash.

pitrou

Choose a reason for hiding this comment

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

I believe the fix is somehow incomplete, see below.
Also, as you say, the problem is "is it safe to destroy the GIL if there are still daemon threads trying to take it?".

@@ -243,6 +283,18 @@ take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate)
MUTEX_UNLOCK(gil->mutex);
if (thread_must_exit(tstate)) {

Choose a reason for hiding this comment

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

I'm not sure why you're doing this here. It doesn't seem necessary and, furthermore, it's unlikely to trigger.

Choose a reason for hiding this comment

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

{
int err = errno;
if (thread_must_exit(tstate)) {

Choose a reason for hiding this comment

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

Ok, but shouldn't you do this after COND_TIMED_WAIT below as well?

@bedevere-bot

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@vstinner

vstinner

to run after wait_for_thread_shutdown() and before Py_Finalize()
completes. For example, when _PyImport_Cleanup() executes Python
code. */
MUTEX_UNLOCK(gil->mutex);

Choose a reason for hiding this comment

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

I'm not sure if anyone else should be done here.

Choose a reason for hiding this comment

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

For example, is COND_SIGNAL(gil->cond) needed to wake up the next thread waiting on COND_TIMED_WAIT()?

@vstinner

I have made the requested changes; please review again.

@bedevere-bot

Thanks for making the requested changes!

@pitrou: please review the changes made to this pull request.

@vstinner

I merged PR #18890 which checks if the thread must exit at function exit as well. In short, it restores the Python 3.8 behavior.

I close this PR for now.

We can revisit take_gil() later to try to adjust/optimize it later. I prefer to move step by step.