-
Notifications
You must be signed in to change notification settings - Fork 82
Use try...finally... to ensure buffer is released
#728
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
Use try...finally... to ensure buffer is released
#728
Conversation
jakirkham
left a comment
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.
Tried to call out the key points of this change below and why they matter
Since a block of code is indented the GitHub diff looks more involved than it actually is
So hopefully this clarifies the nature of the change
| ) | ||
| if not PyBuffer_IsContiguous(&pybuf, b"C"): | ||
| self.strides_mv = new_Py_ssize_t_array(self.ndim) | ||
| try: |
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.
The core of this change involves adding a try for the block of code right after PyObject_GetBuffer
| finally: | ||
| PyBuffer_Release(&pybuf) |
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.
Then moving the PyBuffer_Release into a finally block
That way we still release the underlying Py_buffer object if an exception is raised
| if pybuf.suboffsets != NULL: | ||
| raise NotImplementedError("Suboffsets are not supported") |
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.
For example here is one exception we raise
Though it is also possible to wind up with an exception due to some bug in the code below
In any event we want to make sure normal resource cleanup can proceed as usual (without potentially causing segfaults)
vyasr
left a comment
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.
Ah OK this is fine. #692 (comment) made it sound like you wanted the PyObject_GetBuffer call itself inside a try-except block, which didn't make sense to me since it wouldn't be throwing if that failed. I agree that this change makes sense to avoid leaking the buffer if anything fails in the interim.
|
/merge |
|
Thanks Vyas! 🙏 Yeah can understand how what I said there was unclear. Probably I should have commented on the release line or drew a clearer connection between the acquisition & release as I did here |
|
Should have clarified one other point
That said, I don't think we need to do anything special in this case as |
Yes it can raise, but a Python try-except block is not going to do anything to catch an exception raised by a CPython function. You have to check the return value and then manually reraise, hence why I was confused by the try-except suggestion. We could update the code to do that, but I think we know that we never call this function with an input that will raise so I didn't bother to do that here. |
Follow up on this discussion: #692 (comment)
Ensure that the acquired buffer is properly released even if an exception is raised. Given we may raise an exception, this is important to check.
cc @vyasr