=== 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();