-
Notifications
You must be signed in to change notification settings - Fork 788
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
Prevent dropping unsendable classes on other threads. #3176
Conversation
I am wondering whether someone might (unsafely) depend on Put differently, I think we could actually just not run (We could enforce boxing up-front for
With my maintainer hat on, I whole-heartedly agree. But I actually am a user of that feature: I had simulations which were not thread safe internally for performance reasons (but parallelized by running multiple instances in multiple processes). They would never be moved between threads (or actually be used in multi-threaded programs) and I would be totally fine with aborting the process if dropping these classes on the wrong thread was attempted. |
Meaning that if we do want to give the guarantee of |
At the moment I think the nature of the Python C-API exposing objects as It's probably best if we don't rely on So I think this means we're in agreement that if the object is sent to another thread, on drop we can report it with Python will then free the memory anyway as it controls the allocation. |
Yes, I think this the best course of action. Please feel free to hijack this PR if you have time available. Otherwise, I will try to implement the above here eventually. |
I'll see how things shape up during the week; recently I have been able to scrap together just enough time in the evenings to comment on some of the backlog of issues and PRs in my inbox :) |
7afd658
to
ee4e831
Compare
I added the minimal implementation here and extended the test case to actually check the intended effect, i.e. that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me, thanks! Just one thought on the test.
240e117
to
074f9e1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
bors r+
3176: Prevent dropping unsendable classes on other threads. r=davidhewitt a=adamreichold Continuing the discussed from #3169 (comment) and #3169 (comment): We already have checks in place to avoid borrowing these classes on other threads but it was still possible to send them to another thread and drop them there (while holding the GIL). This change avoids running the `Drop` implementation in such a case even though Python will still free the underlying memory. This might leak resources owned by the object, but it avoids undefined behaviour due to access the unsendable type from another thread. This does assume that the object was not unsafely integrated into an intrusive data structures which still point to the now freed memory. In that case, the only recourse would be to abort the process as freeing the memory is unavoidable when the tp_dealloc slot is called. (And moving it elsewhere into a new allocation would still break any existing pointers.) Co-authored-by: Adam Reichold <[email protected]>
Build failed:
|
Ah, the tests using |
We already have checks in place to avoid borrowing these classes on other threads but it was still possible to send them to another thread and drop them there (while holding the GIL). This change avoids running the `Drop` implementation in such a case even though Python will still free the underlying memory. This might leak resources owned by the object, but it avoids undefined behaviour due to access the unsendable type from another thread. This does assume that the object was not unsafely integrated into an intrusive data structures which still point to the now freed memory. In that case, the only recourse would be to abort the process as freeing the memory is unavoidable when the tp_dealloc slot is called. (And moving it elsewhere into a new allocation would still break any existing pointers.)
074f9e1
to
0ce4eaa
Compare
Added the relevant bors r=davidhewitt |
3176: Prevent dropping unsendable classes on other threads. r=davidhewitt a=adamreichold Continuing the discussed from #3169 (comment) and #3169 (comment): We already have checks in place to avoid borrowing these classes on other threads but it was still possible to send them to another thread and drop them there (while holding the GIL). This change avoids running the `Drop` implementation in such a case even though Python will still free the underlying memory. This might leak resources owned by the object, but it avoids undefined behaviour due to access the unsendable type from another thread. This does assume that the object was not unsafely integrated into an intrusive data structures which still point to the now freed memory. In that case, the only recourse would be to abort the process as freeing the memory is unavoidable when the tp_dealloc slot is called. (And moving it elsewhere into a new allocation would still break any existing pointers.) Co-authored-by: Adam Reichold <[email protected]>
…pping unsendable elsewhere calls into sys.unraisablehook
0ce4eaa
to
e85bfcc
Compare
Canceled. |
And let's try again, but not on WASM... bors retry |
Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
Continuing the discussed from #3169 (comment) and #3169 (comment):
We already have checks in place to avoid borrowing these classes on other threads but it was still possible to send them to another thread and drop them there (while holding the GIL).
This change avoids running the
Drop
implementation in such a case even though Python will still free the underlying memory. This might leak resources owned by the object, but it avoids undefined behaviour due to access the unsendable type from another thread.This does assume that the object was not unsafely integrated into an intrusive data structures which still point to the now freed memory. In that case, the only recourse would be to abort the process as freeing the memory is unavoidable when the tp_dealloc slot is called. (And moving it elsewhere into a new allocation would still break any existing pointers.)