summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-09-13 14:16:46 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-09-13 14:16:46 (GMT)
commit1df1536fb98c1c2bbeefe373bc38877129f905e1 (patch)
treea1489c86f4f1ea5b0645afcabf8aee765826d18a /Python
parentbea8ae794873485eef1b0c0c20b374df99858430 (diff)
downloadcpython-1df1536fb98c1c2bbeefe373bc38877129f905e1.zip
cpython-1df1536fb98c1c2bbeefe373bc38877129f905e1.tar.gz
cpython-1df1536fb98c1c2bbeefe373bc38877129f905e1.tar.bz2
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.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c13
-rw-r--r--Python/ceval_gil.h21
-rw-r--r--Python/pythonrun.c4
3 files changed, 34 insertions, 4 deletions
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