]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-144969: Document that the free threading GC can change ob_tid (#144972)
authorSam Gross <colesbury@gmail.com>
Thu, 19 Feb 2026 00:49:09 +0000 (19:49 -0500)
committerGitHub <noreply@github.com>
Thu, 19 Feb 2026 00:49:09 +0000 (01:49 +0100)
Include/internal/pycore_critical_section.h
InternalDocs/garbage_collector.md

index 60b6fc4a72e88f8487e0cee774c5e5552ed8a613..2a2846b1296b9017e8970058aae2d643d66c576b 100644 (file)
@@ -50,6 +50,15 @@ extern "C" {
 // Asserts that the mutex for the given object is locked. The mutex must
 // be held by the top-most critical section otherwise there's the
 // possibility that the mutex would be swalled out in some code paths.
+//
+// NOTE: We use Py_REFCNT(op) != 1 instead of
+// !PyUnstable_Object_IsUniquelyReferenced(op) because the free threading
+// GC can change an object's ob_tid (it overwrites ob_tid and later
+// restores it from the mimalloc segment).  This means
+// PyUnstable_Object_IsUniquelyReferenced() may spuriously return false
+// after a GC collection, even though the thread may still have exclusive
+// access to the object.  The refcount check is a looser but still catches
+// most misuses.
 #ifdef Py_DEBUG
 
 # define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op)                           \
index a7d872f3ec439210e46b9d59cd91cfc9e1f227a0..94e6fb05b68d6fc3fb885ca844c1eaec928fbfe0 100644 (file)
@@ -153,7 +153,11 @@ pointer-sized (that is, eight bytes on a 64-bit platform).
 
 The garbage collector also temporarily repurposes the `ob_tid` (thread ID)
 and `ob_ref_local` (local reference count) fields for other purposes during
-collections.
+collections.  The `ob_tid` field is later restored from the containing
+mimalloc segment data structure.  In some cases, such as when the original
+allocating thread exits, this can result in a different `ob_tid` value.
+Code should not rely on `ob_tid` being stable across operations that may
+trigger garbage collection.
 
 
 C APIs