Index: Python/ceval.c =================================================================== --- Python/ceval.c (revision 60023) +++ Python/ceval.c (working copy) @@ -214,6 +214,7 @@ static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */ static long main_thread = 0; +static int stay_forever = 0; int PyEval_ThreadsInitialized(void) @@ -234,23 +235,34 @@ void PyEval_AcquireLock(void) { + if (stay_forever && main_thread == PyThread_get_thread_ident()) + return; PyThread_acquire_lock(interpreter_lock, 1); } void PyEval_ReleaseLock(void) { + if (stay_forever && main_thread == PyThread_get_thread_ident()) + return; PyThread_release_lock(interpreter_lock); } void +PyEval_StayForever(void) +{ + assert(main_thread == PyThread_get_thread_ident()); + stay_forever = 1; +} + +void PyEval_AcquireThread(PyThreadState *tstate) { if (tstate == NULL) Py_FatalError("PyEval_AcquireThread: NULL new thread state"); /* Check someone has called PyEval_InitThreads() to create the lock */ assert(interpreter_lock); - PyThread_acquire_lock(interpreter_lock, 1); + PyEval_AcquireLock(); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError( "PyEval_AcquireThread: non-NULL old thread state"); @@ -263,7 +275,7 @@ Py_FatalError("PyEval_ReleaseThread: NULL thread state"); if (PyThreadState_Swap(NULL) != tstate) Py_FatalError("PyEval_ReleaseThread: wrong thread state"); - PyThread_release_lock(interpreter_lock); + PyEval_ReleaseLock(); } /* This function is called from PyOS_AfterFork to ensure that newly @@ -298,7 +310,7 @@ Py_FatalError("PyEval_SaveThread: NULL tstate"); #ifdef WITH_THREAD if (interpreter_lock) - PyThread_release_lock(interpreter_lock); + PyEval_ReleaseLock(); #endif return tstate; } @@ -311,7 +323,7 @@ #ifdef WITH_THREAD if (interpreter_lock) { int err = errno; - PyThread_acquire_lock(interpreter_lock, 1); + PyEval_AcquireLock(); errno = err; } #endif @@ -837,11 +849,11 @@ if (PyThreadState_Swap(NULL) != tstate) Py_FatalError("ceval: tstate mix-up"); - PyThread_release_lock(interpreter_lock); + PyEval_ReleaseLock(); /* Other threads may run now */ - PyThread_acquire_lock(interpreter_lock, 1); + PyEval_AcquireLock(); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate"); Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (revision 60023) +++ Python/pythonrun.c (working copy) @@ -440,6 +440,8 @@ _Py_PrintReferences(stderr); #endif /* Py_TRACE_REFS */ + PyEval_StayForever(); + /* Clear interpreter state */ PyInterpreterState_Clear(interp);