@@ -224,9 +224,14 @@ thread_canary_register(PyThreadState *tstate)
224224 the reference) and in 'tls->local_thread_canary' (which doesn't). */
225225 assert (Py_REFCNT (canary ) == 1 );
226226 tls -> local_thread_canary = canary ;
227- tstate -> gilstate_counter ++ ;
228- /* ^^^ this means 'tstate' will never be automatically freed by
229- PyGILState_Release() */
227+ {
228+ /* this extra PyGILState_Ensure() is deliberately never paired
229+ with a PyGILState_Release(), so 'tstate' is never
230+ automatically freed by PyGILState_Release() */
231+ PyGILState_STATE state = PyGILState_Ensure ();
232+ assert (state == PyGILState_LOCKED );
233+ (void )state ;
234+ }
230235 //fprintf(stderr, "CANARY: ready, tstate=%p, tls=%p, canary=%p\n", tstate, tls, canary);
231236 return ;
232237
@@ -313,52 +318,16 @@ static void restore_errno_only(void)
313318#endif
314319
315320
316- /* MESS. We can't use PyThreadState_GET(), because that calls
317- PyThreadState_Get() which fails an assert if the result is NULL.
318-
319- * in Python 2.7 and <= 3.4, the variable _PyThreadState_Current
320- is directly available, so use that.
321-
322- * in Python 3.5, the variable is available too, but it might be
323- the case that the headers don't define it (this changed in 3.5.1).
324- In case we're compiling with 3.5.x with x >= 1, we need to
325- manually define this variable.
326-
327- * in Python >= 3.6 there is _PyThreadState_UncheckedGet().
328- It was added in 3.5.2 but should never be used in 3.5.x
329- because it is not available in 3.5.0 or 3.5.1.
330- */
331- static PyThreadState * get_current_ts (void )
332- {
333- #if PY_VERSION_HEX >= 0x030D0000
334- return PyThreadState_GetUnchecked ();
335- #else
336- return _PyThreadState_UncheckedGet ();
337- #endif
338- }
339-
340321static PyGILState_STATE gil_ensure (void )
341322{
342- /* Called at the start of a callback. Replacement for
343- PyGILState_Ensure().
344- */
323+ /* Called at the start of a callback. */
345324 PyGILState_STATE result ;
346325 PyThreadState * ts = PyGILState_GetThisThreadState ();
347326 //fprintf(stderr, "%p: gil_ensure(), tstate=%p, tls=%p\n", get_cffi_tls(), ts, get_cffi_tls());
348327
349328 if (ts != NULL ) {
350- ts -> gilstate_counter ++ ;
351- if (ts != get_current_ts ()) {
352- /* common case: 'ts' is our non-current thread state and
353- we have to make it current and acquire the GIL */
354- PyEval_RestoreThread (ts );
355- //fprintf(stderr, "%p: gil_ensure(), tstate=%p MADE CURRENT\n", get_cffi_tls(), ts);
356- return PyGILState_UNLOCKED ;
357- }
358- else {
359- //fprintf(stderr, "%p: gil_ensure(), tstate=%p ALREADY CURRENT\n", get_cffi_tls(), ts);
360- return PyGILState_LOCKED ;
361- }
329+ /* common case: this thread already has a thread state */
330+ return PyGILState_Ensure ();
362331 }
363332 else {
364333 /* no thread state here so far. */
@@ -368,8 +337,6 @@ static PyGILState_STATE gil_ensure(void)
368337 ts = PyGILState_GetThisThreadState ();
369338 //fprintf(stderr, "%p: gil_ensure(), made a new tstate=%p\n", get_cffi_tls(), ts);
370339 assert (ts != NULL );
371- assert (ts == get_current_ts ());
372- assert (ts -> gilstate_counter >= 1 );
373340
374341 /* Use the ThreadCanary mechanism to keep 'ts' alive until the
375342 thread really shuts down */
0 commit comments