]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
authorAntoine Pitrou <solipsis@pitrou.net>
Mon, 13 Sep 2010 14:16:46 +0000 (14:16 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Mon, 13 Sep 2010 14:16:46 +0000 (14:16 +0000)
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.

Include/ceval.h
Misc/NEWS
Python/ceval.c
Python/ceval_gil.h
Python/pythonrun.c

index e55f4b4efb99787110d0cbecd82af2ffd75bb288..2acde13a65499dd306f6b78392d1619d2d7021a4 100644 (file)
@@ -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);
index caec74953b6d39ee38a08898d9dfc3dc65f6e63b..22818923278946532d754dddb4c2ba6a14f77a5a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.
index a181ca83fe7b1807177a98d6ab38e90fc616e94d..48b567865296ff15ea6d769f130669262b194ad9 100644 (file)
@@ -312,6 +312,15 @@ PyEval_InitThreads(void)
         pending_lock = PyThread_allocate_lock();
 }
 
+void
+_PyEval_FiniThreads(void)
+{
+    if (!gil_created())
+        return;
+    destroy_gil();
+    assert(!gil_created());
+}
+
 void
 PyEval_AcquireLock(void)
 {
@@ -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);
index 7d72016083fa1cb0b2cf74c44d7f8ae80f7c6c7a..40e45f75f2e77988c70b28dd0e996370cbf0f995 100644 (file)
@@ -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();
 }
 
index fd31974cb85dc7a03eed09ab9a5c711f48d5a696..8f4e9f18f7e0409c801c00a320b902e0fc3404f3 100644 (file)
@@ -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