diff -r 3ff40811aeed -r 896cf79a19a7 Include/ceval.h --- a/Include/ceval.h Thu Aug 25 15:01:15 2011 +0200 +++ b/Include/ceval.h Mon Aug 29 10:44:10 2011 +0200 @@ -184,6 +184,12 @@ #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ } +/* two internal functions that can be overridden by 3rd-party modules + that want to take more precise control over the GIL */ +typedef void (*_PyEval_GIL_func)(PyThreadState *); +PyAPI_DATA(_PyEval_GIL_func) _PyEval_TakeGIL; +PyAPI_DATA(_PyEval_GIL_func) _PyEval_DropGIL; + #else /* !WITH_THREAD */ #define Py_BEGIN_ALLOW_THREADS { diff -r 3ff40811aeed -r 896cf79a19a7 Python/ceval.c --- a/Python/ceval.c Thu Aug 25 15:01:15 2011 +0200 +++ b/Python/ceval.c Mon Aug 29 10:44:10 2011 +0200 @@ -294,6 +294,9 @@ #include "ceval_gil.h" +_PyEval_GIL_func _PyEval_TakeGIL = take_gil; +_PyEval_GIL_func _PyEval_DropGIL = drop_gil; + int PyEval_ThreadsInitialized(void) { @@ -306,7 +309,7 @@ if (gil_created()) return; create_gil(); - take_gil(PyThreadState_GET()); + _PyEval_TakeGIL(PyThreadState_GET()); main_thread = PyThread_get_thread_ident(); if (!pending_lock) pending_lock = PyThread_allocate_lock(); @@ -327,7 +330,7 @@ PyThreadState *tstate = PyThreadState_GET(); if (tstate == NULL) Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); - take_gil(tstate); + _PyEval_TakeGIL(tstate); } void @@ -337,7 +340,7 @@ We therefore avoid PyThreadState_GET() which dumps a fatal error in debug mode. */ - drop_gil((PyThreadState*)_Py_atomic_load_relaxed( + _PyEval_DropGIL((PyThreadState*)_Py_atomic_load_relaxed( &_PyThreadState_Current)); } @@ -348,7 +351,7 @@ Py_FatalError("PyEval_AcquireThread: NULL new thread state"); /* Check someone has called PyEval_InitThreads() to create the lock */ assert(gil_created()); - take_gil(tstate); + _PyEval_TakeGIL(tstate); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError( "PyEval_AcquireThread: non-NULL old thread state"); @@ -361,7 +364,7 @@ Py_FatalError("PyEval_ReleaseThread: NULL thread state"); if (PyThreadState_Swap(NULL) != tstate) Py_FatalError("PyEval_ReleaseThread: wrong thread state"); - drop_gil(tstate); + _PyEval_DropGIL(tstate); } /* This function is called from PyOS_AfterFork to ensure that newly @@ -379,7 +382,7 @@ return; recreate_gil(); pending_lock = PyThread_allocate_lock(); - take_gil(tstate); + _PyEval_TakeGIL(tstate); main_thread = PyThread_get_thread_ident(); /* Update the threading module with the new state. @@ -426,7 +429,7 @@ Py_FatalError("PyEval_SaveThread: NULL tstate"); #ifdef WITH_THREAD if (gil_created()) - drop_gil(tstate); + _PyEval_DropGIL(tstate); #endif return tstate; } @@ -439,10 +442,10 @@ #ifdef WITH_THREAD if (gil_created()) { int err = errno; - take_gil(tstate); + _PyEval_TakeGIL(tstate); /* _Py_Finalizing is protected by the GIL */ if (_Py_Finalizing && tstate != _Py_Finalizing) { - drop_gil(tstate); + _PyEval_DropGIL(tstate); PyThread_exit_thread(); assert(0); /* unreachable */ } @@ -1258,11 +1261,11 @@ /* Give another thread a chance */ if (PyThreadState_Swap(NULL) != tstate) Py_FatalError("ceval: tstate mix-up"); - drop_gil(tstate); + _PyEval_DropGIL(tstate); /* Other threads may run now */ - take_gil(tstate); + _PyEval_TakeGIL(tstate); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate"); }