Uh oh!
There was an error while loading. Please reload this page.
Fix async Python functors invoking from multiple C++ threads (#1587) - #1595
Conversation
wjakob
commented
Nov 9, 2018
I'm a bit confused by the change, can you clarify? Specifically, I'm wondering if/why it is safe to |
wjakob
commented
Nov 9, 2018
FWIW what's also missing here is a testcase that would have lead to breakage in the previous implemenation. |
uentity
commented
Nov 9, 2018
@wjakob Your first comment is absolutely right, I missed that point, s.t. all functors became single-shot (can be called only once and fail/crash 2nd time). Fixed that in next commit. Had to introduce local "function handle" struct with custom destructor. Seems that my code is working now. Considering testcase: I can write a Python test with statefull lambda, and it should crash Python (and I suppose we can't catch/prevent it in testing code) without this PR and work fine with it. |
e619e19 to
e3375b6Compareuentity
commented
Nov 9, 2018
@wjakob I've made a test case and squashed [NOTE] test leads to segfault (on my machine) if run without latest commit (with previous |
@wjakob there seems to be a problem with ~func_handle() {
gil_scoped_acquire acq;
function kill_f(std::move(f));
}If I replace it with conventional Python API for acquiring GIL (straight from documentation): ~func_handle() {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
{
function kill_f(std::move(f));
}
PyGILState_Release(gstate);
}then everything works without issues. |
davidhewitt
commented
Dec 1, 2018
Hello @wjakob@uentity, I've authored a separate PR #1556 which resolves the deadlock problem with Below is my summary of what I understand of the problems these PRs are trying to solve.
I would love to contribute in any way possible to help resolve these! |
Hi @davidhewitt! With you PR #1556 applied I can bring back my original implementation of ~func_handle() {
gil_scoped_acquire acq;
function kill_f(std::move(f));
}Very soon after I thought my issue #1587 is solved I've faced the issue of your PR #1556 and fixed it by replacing BTW can you give any comment on comparative "heaviness" of capturing GIL solutions I noted earlier? If I look at |
davidhewitt
commented
Dec 1, 2018
I understand NB I see that #1211 has just been merged which was exactly the same thing that I was trying to solve. So I think that |
| func_handle(const func_handle&) = default; | ||
| ~func_handle() { | ||
| gil_scoped_acquire acq; | ||
| function kill_f(std::move(f)); |
There was a problem hiding this comment.
It might be more clear to explicitly reset the function handle and decrease the reference count: f.release().dec_ref();
There was a problem hiding this comment.
@davidhewitt causes strange test failure on VS with Python 3.6 on x86 platform, so reverted back to original version.
Logs: https://ci.appveyor.com/project/wjakob/pybind11/builds/20894165
uentity
commented
Dec 10, 2018
@wjakob style check is failing because of non-existent URL: |
hammer498
commented
Jun 3, 2019
I was also affected by this and your patch has unblocked me. Thank you @uentity! |
…1587) Ensure GIL is held during functor destruction.
uentity
commented
Jun 6, 2019
@hammer498 you're welcome =) |
wjakob
commented
Jun 11, 2019
This looks good to me now. |
Ensure GIL is released after functor destructor finished (not only
during functor execution as in previous implementation).
This fixes#1587