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
BUG: prevent QHull message stream being closed twice #20611
Conversation
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.
Thanks @andfoy. I don't think this fix is quite correct. self._messages
is a separate object from self._qh
, and can be non-null even if _qh
is null. The logic in __init__
is:
self._qh = NULL
self._messages = MessageStream()
# now do a bunch of things, including validation steps that can raise exceptions
self._qh = malloc(...)
So this change would leave the instantiated MessageStream
open in case an exception is raised before _qh
is allocated, leaking the memory stream or file handle.
MessageStream.close
actually looks safe to call multiple times. Is the problem you are seeing calling it twice and something inside the state of the MessageStream
object not existing anymore, or is it that inside _Qhull
self._messages
itself no longer exists?
Thanks for bringing these points up @rgommers, now that you mentioned it, the I'll add a |
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.
Thanks! LGTM now.
Reference issue
This makes part of the current effort to remove the GIL from Python. After numpy/numpy#26348 and this PR, all the test suite passes successfully when ran locally.
What does this implement/fix?
This PR prevents releasing the
MessageStream
object in QHull twice. This may occur because the deallocation logic is duplicated both in theclose
and the__dealloc__
methods (there's a note mentioning that this is required to support PyPy). Before, a call toclose
followed by__dealloc__
would segfault, sinceclose
would have closed theMessageStream
before__dealloc__
would have attempted to close it, thus trying to free a null pointer.Additional information
This behaviour occurs independent of locking, since the closing attempt would have occurred without checking if
self._qh != NULL