BackgroundTask binding : Release GIL when destroying BackgroundTask #5579
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The BackgroundTask constructor calls
cancelAndWait()
, and a Python function can't be cancelled unless it is able to aquire the GIL. Thus if we don't release the GIL before callingwait()
, we can deadlock. We were already releasing the GIL appropriately for tasks returned byParallelAlgo::callOnBackgroundThread()
but not for those constructed withBackgroundTask()
directly.Fixing this revealed another problem that was dealt with correctly by
callOnBackgroundThread()
but not by theBackgroundTask()
constructor. We need to hold the GIL when destroying the Python function owned by the task, and we were doing this by manually deleting it after it ran, at a point when we knew we had the GIL. But this wasn't sufficient if the BackgroundTask was cancelled before the function even started. In this case, the function would be destroyed from C++ and we would be deleting Python objects without holding the GIL. The solution is again to adopt the GIL management used bycallOnBackgroundThread()
.I'm just making this PR for
main
as the problem only showed up in the LocalDispatcher work I'm doing for 1.4. All current usage of BackgroundTasks goes throughcallOnBackgroundThread()
, so shouldn't suffer from this issue.