Skip to content

gh-128182: Switch ctypes to solely critical sections #132133

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

Merged
merged 11 commits into from
Apr 7, 2025

Conversation

ZeroIntensity
Copy link
Member

@ZeroIntensity ZeroIntensity commented Apr 5, 2025

Removes the LOCK_PTR/UNLOCK_PTR macros, and fixes two races related to missing locks.

} else {
LOCK_PTR(self);
Py_BEGIN_CRITICAL_SECTION(self);
*((void **)self->b_ptr) = dst->b_ptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain again why we can't use locked_deref_assign here? is it because of pointer rules? (because here, we're just re-assigning the stuff right?)

Copy link
Contributor

@kumaraditya303 kumaraditya303 Apr 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to get rid of locked_deref_assign in future so using it less is better. Also that reacquires the critical sections so will cause perf loss

@@ -3347,13 +3366,15 @@ _PyCData_set(ctypes_state *st,
if (err == -1)
return NULL;
if (err) {
locked_memcpy_from(ptr, src, size);
Py_BEGIN_CRITICAL_SECTION(src);
memcpy(ptr, src->b_ptr, size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the critical section should be held longer? because GetKeepedObjects() is calling PyCData_GetContainer() which itself uses Py_BEGIN_CRITICAL_SECTION(src), so aren't we having a re-entrant critical section lock?

Copy link
Member Author

@ZeroIntensity ZeroIntensity Apr 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, which critical sections are allowed to do 😄

We can't release the lock before calling GetKeepedObjects, but I guess we could call GetKeepedObjects_lock_held. Edit: nevermind, that's not a real function.

@kumaraditya303
Copy link
Contributor

The existing usage of locked_memcpy are not thread safe and needs to be reverted back to manual memcpy with holding the critical section.

For example, on this line it acquires the critical section after reading the self->b_size so it is not safe.

locked_memcpy_from(&parg->value, self, self->b_size);

@ZeroIntensity
Copy link
Member Author

Yeah, I'll remove that too.

@python-cla-bot
Copy link

python-cla-bot bot commented Apr 6, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

Copy link
Contributor

@kumaraditya303 kumaraditya303 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are merge conflicts

@bedevere-app
Copy link

bedevere-app bot commented Apr 7, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@ZeroIntensity
Copy link
Member Author

Got rid of locked_memcpy* and locked_deref_assign. That should fix the rest of the thread safety issues here, but we might need to take one extra look at _PyCData_set.

I didn't expect the Spanish Inquisition.

@bedevere-app
Copy link

bedevere-app bot commented Apr 7, 2025

Nobody expects the Spanish Inquisition!

@kumaraditya303: please review the changes made to this pull request.

@bedevere-app bedevere-app bot requested a review from kumaraditya303 April 7, 2025 11:24
@kumaraditya303 kumaraditya303 merged commit 8e260b3 into python:main Apr 7, 2025
44 of 45 checks passed
seehwan pushed a commit to seehwan/cpython that referenced this pull request Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants