8000 Make PyWeakref_NewProxy thread-safe · python/cpython@c4f8453 · GitHub
[go: up one dir, main page]

Skip to content

Commit c4f8453

Browse files
committed
Make PyWeakref_NewProxy thread-safe
1 parent 75603c1 commit c4f8453

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

Objects/weakrefobject.c

Lines changed: 12 additions & 0 deletions
< 8000 td data-grid-cell-id="diff-203baf73fbb7f03732f24a6070851675c64af2e125892f45639e715e83030d61-856-856-0" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative diff-line-number-neutral left-side">856
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,26 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
854854
return NULL;
855855
}
856
list = GET_WEAKREFS_LISTPTR(ob);
857+
/* NB: For free-threaded builds its critical that no code inside the
858+
* critical section can release it. We need to recompute ref/proxy after
859+
* any code that may release the critical section.
860+
*/
861+
Py_BEGIN_CRITICAL_SECTION(ob);
857862
get_basic_refs(*list, &ref, &proxy);
858863
if (callback == Py_None)
859864
callback = NULL;
860865
if (callback == NULL)
861866
/* attempt to return an existing weak reference if it exists */
862867
result = proxy;
868+
#ifdef Py_GIL_DISABLED
869+
/* Incref will fail if the existing weakref is being destroyed */
870+
if (result == NULL ||
871+
!_Py_TryIncref((PyObject **)&result, (PyObject *)result)) {
872+
#else
863873
if (result != NULL)
864874
Py_INCREF(result);
865875
else {
876+
#endif
866877
/* We do not need to recompute ref/proxy; new_weakref cannot
867878
trigger GC.
868879
*/
@@ -888,6 +899,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
888899
insert_after(result, prev);
889900
}
890901
}
902+
Py_END_CRITICAL_SECTION();
891903
return (PyObject *) result;
892904
}
893905

0 commit comments

Comments
 (0)
0