diff options
-rw-r--r-- | Include/ceval.h | 1 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Python/ceval.c | 13 | ||||
-rw-r--r-- | Python/ceval_gil.h | 21 | ||||
-rw-r--r-- | Python/pythonrun.c | 4 |
5 files changed, 39 insertions, 4 deletions
diff --git a/Include/ceval.h b/Include/ceval.h index e55f4b4..2acde13 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -160,6 +160,7 @@ PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); PyAPI_FUNC(void) PyEval_InitThreads(void); +PyAPI_FUNC(void) _PyEval_FiniThreads(void); PyAPI_FUNC(void) PyEval_AcquireLock(void); PyAPI_FUNC(void) PyEval_ReleaseLock(void); PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); @@ -10,6 +10,10 @@ What's New in Python 3.2 Alpha 3? Core and Builtins ----------------- +- Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly + re-created on a subsequent call to Py_Initialize(). The problem (a crash) + wouldn't appear in 3.1 or 2.7 where the GIL's structure is more trivial. + - Issue #9210: Configure option --with-wctype-functions was removed. Using the functions from the libc caused the methods .upper() and lower() to become locale aware and created subtly wrong results. diff --git a/Python/ceval.c b/Python/ceval.c index a181ca8..48b5678 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -313,6 +313,15 @@ PyEval_InitThreads(void) } void +_PyEval_FiniThreads(void) +{ + if (!gil_created()) + return; + destroy_gil(); + assert(!gil_created()); +} + +void PyEval_AcquireLock(void) { PyThreadState *tstate = PyThreadState_GET(); @@ -368,10 +377,6 @@ PyEval_ReInitThreads(void) if (!gil_created()) return; - /*XXX Can't use PyThread_free_lock here because it does too - much error-checking. Doing this cleanly would require - adding a new function to each thread_*.h. Instead, just - create a new lock and waste a little bit of memory */ recreate_gil(); pending_lock = PyThread_allocate_lock(); take_gil(tstate); diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h index 7d72016..40e45f7 100644 --- a/Python/ceval_gil.h +++ b/Python/ceval_gil.h @@ -95,6 +95,9 @@ do { \ #define MUTEX_INIT(mut) \ if (pthread_mutex_init(&mut, NULL)) { \ Py_FatalError("pthread_mutex_init(" #mut ") failed"); }; +#define MUTEX_FINI(mut) \ + if (pthread_mutex_destroy(&mut)) { \ + Py_FatalError("pthread_mutex_destroy(" #mut ") failed"); }; #define MUTEX_LOCK(mut) \ if (pthread_mutex_lock(&mut)) { \ Py_FatalError("pthread_mutex_lock(" #mut ") failed"); }; @@ -106,6 +109,9 @@ do { \ #define COND_INIT(cond) \ if (pthread_cond_init(&cond, NULL)) { \ Py_FatalError("pthread_cond_init(" #cond ") failed"); }; +#define COND_FINI(cond) \ + if (pthread_cond_destroy(&cond)) { \ + Py_FatalError("pthread_cond_destroy(" #cond ") failed"); }; #define COND_SIGNAL(cond) \ if (pthread_cond_signal(&cond)) { \ Py_FatalError("pthread_cond_signal(" #cond ") failed"); }; @@ -305,9 +311,24 @@ static void create_gil(void) _Py_atomic_store_explicit(&gil_locked, 0, _Py_memory_order_release); } +static void destroy_gil(void) +{ + MUTEX_FINI(gil_mutex); +#ifdef FORCE_SWITCHING + MUTEX_FINI(switch_mutex); +#endif + COND_FINI(gil_cond); +#ifdef FORCE_SWITCHING + COND_FINI(switch_cond); +#endif + _Py_atomic_store_explicit(&gil_locked, -1, _Py_memory_order_release); + _Py_ANNOTATE_RWLOCK_DESTROY(&gil_locked); +} + static void recreate_gil(void) { _Py_ANNOTATE_RWLOCK_DESTROY(&gil_locked); + /* XXX should we destroy the old OS resources here? */ create_gil(); } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index fd31974..8f4e9f1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -514,6 +514,10 @@ Py_Finalize(void) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); +#ifdef WITH_THREAD + _PyEval_FiniThreads(); +#endif + #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed |