Skip to content

bpo-39877: take_gil() now exits the thread if finalizing #18854

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 and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed

bpo-39877: take_gil() now exits the thread if finalizing #18854

wants to merge 2 commits into from

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Mar 8, 2020

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

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
Copy link
Member Author

vstinner commented Mar 8, 2020

@pitrou: My previous change introduced a race condition: https://bugs.python.org/issue39877#msg363667 This change should fix it.

@vstinner
Copy link
Member Author

vstinner commented Mar 8, 2020

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

Copy link
Member

@pitrou pitrou left a comment

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)) {
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

This code path is to prevent https://bugs.python.org/issue39877#msg363667 crash. Are you suggesting to move this code at line 249, after COND_TIMED_WAIT()?

thread_must_exit() at entry is to prevent https://bugs.python.org/issue39877#msg363512 crash.

{
int err = errno;

if (thread_must_exit(tstate)) {
Copy link
Member

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
Copy link

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

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

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.

Copy link
Member Author

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
Copy link
Member Author

vstinner commented Mar 9, 2020

I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

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

@vstinner
Copy link
Member Author

vstinner commented Mar 9, 2020

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.

@vstinner vstinner closed this Mar 9, 2020
@vstinner vstinner deleted the take_gil_exit branch March 9, 2020 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants