@@ -119,6 +119,8 @@ _Py_brc_merge_refcounts(PyThreadState *tstate)
119
119
struct _brc_thread_state * brc = & ((_PyThreadStateImpl * )tstate )-> brc ;
120
120
struct _brc_bucket * bucket = get_bucket (tstate -> interp , brc -> tid );
121
121
122
+ assert (brc -> tid == _Py_ThreadId ());
123
+
122
124
// Append all objects into a local stack. We don't want to hold the lock
123
125
// while calling destructors.
124
126
PyMutex_Lock (& bucket -> mutex );
@@ -142,11 +144,12 @@ void
142
144
_Py_brc_init_thread (PyThreadState * tstate )
143
145
{
144
146
struct _brc_thread_state * brc = & ((_PyThreadStateImpl * )tstate )-> brc ;
145
- brc -> tid = _Py_ThreadId ();
147
+ uintptr_t tid = _Py_ThreadId ();
146
148
147
149
// Add ourself to the hashtable
148
- struct _brc_bucket * bucket = get_bucket (tstate -> interp , brc -> tid );
150
+ struct _brc_bucket * bucket = get_bucket (tstate -> interp , tid );
149
151
PyMutex_Lock (& bucket -> mutex );
152
+ brc -> tid = tid ;
150
153
llist_insert_tail (& bucket -> root , & brc -> bucket_node );
151
154
PyMutex_Unlock (& bucket -> mutex );
152
155
}
@@ -155,6 +158,13 @@ void
155
158
_Py_brc_remove_thread (PyThreadState * tstate )
156
159
{
157
160
struct _brc_thread_state * brc = & ((_PyThreadStateImpl * )tstate )-> brc ;
161
+ if (brc -> tid == 0 ) {
162
+ // The thread state may have been created, but never bound to a native
163
+ // thread and therefore never added to the hashtable.
164
+ assert (tstate -> _status .bound == 0 );
165
+ return ;
166
+ }
167
+
158
168
struct _brc_bucket * bucket = get_bucket (tstate -> interp , brc -> tid );
159
169
160
170
// We need to fully process any objects to merge before removing ourself
0 commit comments