@@ -3310,6 +3310,11 @@ PyUnstable_InterpreterView_FromDefault(void)
33103310 return (PyInterpreterView )view ;
33113311}
33123312
3313+ // This is a bit of a hack -- since 0 is reserved for failure, we need
3314+ // to have our own sentinel for when we want to indicate that no prior
3315+ // thread state was attached.
3316+ static int NO_TSTATE_SENTINEL = 0 ;
3317+
33133318PyThreadView
33143319PyThreadState_Ensure (PyInterpreterLock lock )
33153320{
@@ -3318,7 +3323,7 @@ PyThreadState_Ensure(PyInterpreterLock lock)
33183323 if (attached_tstate != NULL && attached_tstate -> interp == interp ) {
33193324 /* Yay! We already have an attached thread state that matches. */
33203325 ++ attached_tstate -> ensure .counter ;
3321- return 0 ;
3326+ return ( PyThreadView ) & NO_TSTATE_SENTINEL ;
33223327 }
33233328
33243329 PyThreadState * detached_gilstate = gilstate_get ();
@@ -3327,13 +3332,13 @@ PyThreadState_Ensure(PyInterpreterLock lock)
33273332 assert (attached_tstate == NULL );
33283333 ++ detached_gilstate -> ensure .counter ;
33293334 _PyThreadState_Attach (detached_gilstate );
3330- return 0 ;
3335+ return ( PyThreadView ) & NO_TSTATE_SENTINEL ;
33313336 }
33323337
33333338 PyThreadState * fresh_tstate = _PyThreadState_NewBound (interp ,
33343339 _PyThreadState_WHENCE_GILSTATE );
33353340 if (fresh_tstate == NULL ) {
3336- return -1 ;
3341+ return 0 ;
33373342 }
33383343 fresh_tstate -> ensure .counter = 1 ;
33393344 fresh_tstate -> ensure .delete_on_release = 1 ;
@@ -3344,7 +3349,7 @@ PyThreadState_Ensure(PyInterpreterLock lock)
33443349 _PyThreadState_Attach (fresh_tstate );
33453350 }
33463351
3347- return 0 ;
3352+ return ( PyThreadView ) & NO_TSTATE_SENTINEL ;
33483353}
33493354
33503355void
@@ -3357,7 +3362,13 @@ PyThreadState_Release(PyThreadView thread_view)
33573362 Py_FatalError ("PyThreadState_Release() called more times than PyThreadState_Ensure()" );
33583363 }
33593364 // The thread view might be NULL
3360- PyThreadState * to_restore = (PyThreadState * )thread_view ;
3365+ PyThreadState * to_restore ;
3366+ if (thread_view == (PyThreadView )& NO_TSTATE_SENTINEL ) {
3367+ to_restore = NULL ;
3368+ }
3369+ else {
3370+ to_restore = (PyThreadState * )thread_view ;
3371+ }
33613372 if (remaining == 0 ) {
33623373 if (tstate -> ensure .delete_on_release ) {
33633374 PyThreadState_Clear (tstate );
0 commit comments