Skip to content
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

Fix issue with PyObject drop and allow_threads #913

Merged
merged 1 commit into from
May 8, 2020

Conversation

davidhewitt
Copy link
Member

While writing tests for #908 I realised unfortunately there is a bad interaction between the optimization I wrote in #851 and allow_threads.

With the GIL_COUNT method for gil_is_acquired, it's not possible to know if we are inside an allow_threads call without the GIL. The way #851 is currently written, in this situation we end up decreasing a reference count without the GIL held, which could cause all kind of bad stuff.

I propose to fix this situation by introducing a linked-list of GIL states, which is updated by both GILPool and allow_threads.

This fix is still broken if someone wishes to use the PyEval_SaveThread APIs themselves manually. If you think we need to worry about the case of users using PyEval_SaveThread themselves, then I think the only sensible solution is to revert #851.

I think the implementation here can still be cleaned up a lot. I wanted to open this PR to discuss the problem before I bothered to make the solution particularly tidy.

(I have also checked benchmarks and it does not noticeably affect performance.)

Let me know if you think I should finish this fix, or revert #851.

@kngwyu
Copy link
Member

kngwyu commented May 7, 2020

I'm sorry I don't completely understand the problem yet, but how about just setting it to zero?
E.g.,

        unsafe {
            let save = ffi::PyEval_SaveThread();
            let count = GIL_COUNT.with(|c| c.get());
            GIL_COUNT.with(|c| c.set(0));
            let result = f();
            GIL_COUNT.with(|c| c.set(count));
            ffi::PyEval_RestoreThread(save);
            result
        }

@davidhewitt
Copy link
Member Author

Haha nice yes that will also solve the problem in a much simpler way! 😆

@davidhewitt
Copy link
Member Author

davidhewitt commented May 7, 2020

Cool @kngwyu the simpler solution is much nicer 👍 👍 👍

(I've pushed that now, ready for you to review.)

@kngwyu
Copy link
Member

kngwyu commented May 8, 2020

Thank you!

@kngwyu kngwyu merged commit 027c90c into PyO3:master May 8, 2020
@davidhewitt davidhewitt deleted the gil_state_list branch August 10, 2021 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants