=== modified file 'Include/ceval.h' --- Include/ceval.h 2006-02-15 17:27:45 +0000 +++ Include/ceval.h 2008-05-07 16:34:26 +0000 @@ -129,6 +129,7 @@ PyAPI_FUNC(void) PyEval_ReleaseLock(void); PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); +PyAPI_FUNC(void) _PyEval_StayForever(void); PyAPI_FUNC(void) PyEval_ReInitThreads(void); #define Py_BEGIN_ALLOW_THREADS { \ === modified file 'Include/import.h' --- Include/import.h 2008-01-03 22:16:32 +0000 +++ Include/import.h 2008-05-07 16:43:13 +0000 @@ -30,6 +30,7 @@ PyAPI_FUNC(struct filedescr *) _PyImport_FindModule( const char *, PyObject *, char *, size_t, FILE **, PyObject **); PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *); +PyAPI_FUNC(void) _PyImport_LockForever(void); PyAPI_FUNC(void) _PyImport_ReInitLock(void); PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *); === modified file 'Python/ceval.c' --- Python/ceval.c 2008-04-27 18:40:21 +0000 +++ Python/ceval.c 2008-05-07 17:45:27 +0000 @@ -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(!interpreter_lock || 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"); === modified file 'Python/import.c' --- Python/import.c 2008-03-27 10:35:52 +0000 +++ Python/import.c 2008-05-07 17:22:50 +0000 @@ -316,6 +316,13 @@ #endif +void +_PyImport_LockForever(void) +{ + /* No matching unlock. Should be sufficient. */ + lock_import(); +} + static PyObject * imp_lock_held(PyObject *self, PyObject *noargs) { === modified file 'Python/pythonrun.c' --- Python/pythonrun.c 2008-04-12 23:44:07 +0000 +++ Python/pythonrun.c 2008-05-07 18:01:38 +0000 @@ -347,7 +347,10 @@ * the threads created via Threading. */ call_sys_exitfunc(); + + _PyImport_LockForever(); initialized = 0; + _PyEval_StayForever(); /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET();