Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.3k
gh-133931: Introduce _PyObject_XSetRefDelayed to replace Py_XSETREF#134377
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Objects/obmalloc.c Outdated
_PyObject_XSetRefDelayed(PyObject **ptr, PyObject *value) | ||
{ | ||
PyObject *old = *ptr; | ||
FT_ATOMIC_STORE_PTR_RELEASE(*ptr, Py_NewRef(value)); |
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 default build implementation inpycore_pymem.h
doesn't include thePy_NewRef()
.
My preference is to keep thePy_NewRef(value)
in the callers, i.e.:
_PyObject_XSetRefDelayed(dictptr,Py_NewRef(value));
to match the semantics ofPy_XSETREF
.
Interesting... CI passed in my local but not in the CI.. :( |
Ah okay..
|
Why do we need Also, what is "delayed"? Either choose a clearer name, or add an explanatory comment in the header file. |
corona10 commentedJun 7, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
IIUC, the critical section is for the root object to prevent other threads from mutating the child object, and a delayed reference to prevent use-after-free from other threads that reference the child object. |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Gentle ping@kumaraditya303@vstinner |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Objects/genobject.c Outdated
@@ -718,15 +720,19 @@ gen_set_name(PyObject *self, PyObject *value, void *Py_UNUSED(ignored)) | |||
"__name__ must be set to a string object"); | |||
return -1; | |||
} | |||
Py_XSETREF(op->gi_name, Py_NewRef(value)); | |||
Py_BEGIN_CRITICAL_SECTION(self); | |||
// To prevent use-after-free from other threads that reference the gi_name. |
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.
Maybe addgh-133931:
prefix to these comments.
Include/internal/pycore_pymem.h Outdated
#ifdef Py_GIL_DISABLED | ||
// Same as `Py_XSETREF` but in free-threading, it stores the object atomically | ||
// and queues the old object to be decrefed at a safe point using QSBR. | ||
PyAPI_FUNC(void) _PyObject_XSetRefDelayed(PyObject **p_obj, PyObject *obj); |
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.
Why not adding this function topycore_object.h
header instead?
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.
Because _PyObject_XDecRefDelayed is also declared here?
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.
I think it's fine to place_PyObject_XDecRefDelayed
and_PyObject_XSetRefDelayed
inpycore_object.h
instead if you prefer. (I agree that they should probably be in the same header as each other).
Objects/typeobject.c Outdated
@@ -3967,7 +3967,8 @@ _PyObject_SetDict(PyObject *obj, PyObject *value) | |||
return -1; | |||
} | |||
Py_BEGIN_CRITICAL_SECTION(obj); | |||
// To prevent use-after-free from other threads that reference the __dict__ | |||
// gh-133931: To prevent use-after-free from other threads that reference |
efimov-mikhailJun 16, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
Is it correct issue reference for__dict__
too?
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 good - a few comments below
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Include/internal/pycore_pymem.h Outdated
#ifdef Py_GIL_DISABLED | ||
// Same as `Py_XSETREF` but in free-threading, it stores the object atomically | ||
// and queues the old object to be decrefed at a safe point using QSBR. | ||
PyAPI_FUNC(void) _PyObject_XSetRefDelayed(PyObject **p_obj, PyObject *obj); |
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.
I think it's fine to place_PyObject_XDecRefDelayed
and_PyObject_XSetRefDelayed
inpycore_object.h
instead if you prefer. (I agree that they should probably be in the same header as each other).
efimov-mikhail left a comment• edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
efimov-mikhail left a comment• edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
LGTM
Uh oh!
There was an error while loading.Please reload this page.
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.
LGTM
52be7f4
intopython:mainUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
gen_set_name
andgen_set_qualname
thread-safe in free-threaded builds #133931