Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4379)

Unified Diff: Python/pystate.c

Issue 10915: Make the PyGILState API compatible with multiple interpreters
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Modules/_threadmodule.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Python/pystate.c
===================================================================
--- Python/pystate.c (révision 88020)
+++ Python/pystate.c (copie de travail)
@@ -34,11 +34,10 @@
extern "C" {
#endif
-/* The single PyInterpreterState used by this process'
- GILState implementation
+/* The single PyInterpreterState used by the legacy PyGILState_* API
+ (non-Ex variants)
*/
-static PyInterpreterState *autoInterpreterState = NULL;
-static int autoTLSkey = 0;
+static PyInterpreterState *main_interp = NULL;
#else
#define HEAD_INIT() /* Nothing */
#define HEAD_LOCK() /* Nothing */
@@ -53,7 +52,7 @@
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
#ifdef WITH_THREAD
-static void _PyGILState_NoteThreadState(PyThreadState* tstate);
+static void _PyGILState_NoteThreadState(PyInterpreterState *, PyThreadState *);
#endif
@@ -68,6 +67,10 @@
#ifdef WITH_THREAD
if (head_mutex == NULL)
Py_FatalError("Can't initialize threads for interpreter");
+ interp->auto_tls_key = PyThread_create_key();
+ if (interp->auto_tls_key == -1)
+ Py_FatalError("Could not allocate TLS entry");
+ assert(PyThread_get_key_value(interp->auto_tls_key) == NULL);
#endif
interp->modules = NULL;
interp->modules_reloading = NULL;
@@ -147,6 +150,9 @@
if (interp->tstate_head != NULL)
Py_FatalError("PyInterpreterState_Delete: remaining threads");
*p = interp->next;
+#ifdef WITH_THREAD
+ PyThread_delete_key(interp->auto_tls_key);
+#endif
HEAD_UNLOCK();
free(interp);
}
@@ -201,7 +207,7 @@
tstate->c_traceobj = NULL;
if (init)
- _PyThreadState_Init(tstate);
+ _PyThreadState_Init(interp, tstate);
HEAD_LOCK();
tstate->next = interp->tstate_head;
@@ -225,10 +231,10 @@
}
void
-_PyThreadState_Init(PyThreadState *tstate)
+_PyThreadState_Init(PyInterpreterState *interp, PyThreadState *tstate)
{
#ifdef WITH_THREAD
- _PyGILState_NoteThreadState(tstate);
+ _PyGILState_NoteThreadState(interp, tstate);
#endif
}
@@ -336,12 +342,13 @@
void
PyThreadState_Delete(PyThreadState *tstate)
{
+ PyInterpreterState *interp = tstate->interp;
if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current))
Py_FatalError("PyThreadState_Delete: tstate is still current");
tstate_delete_common(tstate);
#ifdef WITH_THREAD
- if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
- PyThread_delete_key_value(autoTLSkey);
+ if (PyThread_get_key_value(interp->auto_tls_key) == tstate)
+ PyThread_delete_key_value(interp->auto_tls_key);
#endif /* WITH_THREAD */
}
@@ -352,13 +359,14 @@
{
PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
&_PyThreadState_Current);
+ PyInterpreterState *interp = tstate->interp;
if (tstate == NULL)
Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate");
_Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
tstate_delete_common(tstate);
- if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
- PyThread_delete_key_value(autoTLSkey);
+ if (interp && PyThread_get_key_value(interp->auto_tls_key) == tstate)
+ PyThread_delete_key_value(interp->auto_tls_key);
PyEval_ReleaseLock();
}
#endif /* WITH_THREAD */
@@ -393,6 +401,7 @@
to it, we need to ensure errno doesn't change.
*/
int err = errno;
+ /* XXX why this and not oldts instead? */
PyThreadState *check = PyGILState_GetThisThreadState();
if (check && check->interp == newts->interp && check != newts)
Py_FatalError("Invalid thread state for this thread");
@@ -557,7 +566,6 @@
PyThreadState_IsCurrent(PyThreadState *tstate)
{
/* Must be the tstate for this thread */
- assert(PyGILState_GetThisThreadState()==tstate);
return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current);
}
@@ -568,21 +576,16 @@
_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
{
assert(i && t); /* must init with valid states */
- autoTLSkey = PyThread_create_key();
- if (autoTLSkey == -1)
- Py_FatalError("Could not allocate TLS entry");
- autoInterpreterState = i;
- assert(PyThread_get_key_value(autoTLSkey) == NULL);
- assert(t->gilstate_counter == 0);
+ main_interp = i;
+ assert(t->gilstate_counter == 1);
- _PyGILState_NoteThreadState(t);
+ _PyGILState_NoteThreadState(i, t);
}
void
_PyGILState_Fini(void)
{
- PyThread_delete_key(autoTLSkey);
- autoInterpreterState = NULL;
+ main_interp = NULL;
}
/* When a thread state is created for a thread by some mechanism other than
@@ -591,14 +594,8 @@
a better fix for SF bug #1010677 than the first one attempted).
*/
static void
-_PyGILState_NoteThreadState(PyThreadState* tstate)
+_PyGILState_NoteThreadState(PyInterpreterState *interp, PyThreadState* tstate)
{
- /* If autoTLSkey isn't initialized, this must be the very first
- threadstate created in Py_Initialize(). Don't do anything for now
- (we'll be back here when _PyGILState_Init is called). */
- if (!autoInterpreterState)
- return;
-
/* Stick the thread state for this thread in thread local storage.
The only situation where you can legitimately have more than one
@@ -613,8 +610,8 @@
state created for that given OS level thread will "win",
which seems reasonable behaviour.
*/
- if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
- Py_FatalError("Couldn't create autoTLSkey mapping");
+ if (PyThread_set_key_value(interp->auto_tls_key, (void *)tstate) < 0)
+ Py_FatalError("Couldn't create auto_tls_key mapping");
/* PyGILState_Release must not try to delete this thread state. */
tstate->gilstate_counter = 1;
@@ -622,15 +619,21 @@
/* The public functions */
PyThreadState *
+PyGILState_GetThisThreadStateEx(PyInterpreterState *interp)
+{
+ return (PyThreadState *)PyThread_get_key_value(interp->auto_tls_key);
+}
+
+PyThreadState *
PyGILState_GetThisThreadState(void)
{
- if (autoInterpreterState == NULL)
+ if (main_interp == NULL)
return NULL;
- return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
+ return (PyThreadState *)PyThread_get_key_value(main_interp->auto_tls_key);
}
PyGILState_STATE
-PyGILState_Ensure(void)
+PyGILState_EnsureEx(PyInterpreterState *interp)
{
int current;
PyThreadState *tcur;
@@ -639,11 +642,11 @@
spells out other issues. Embedders are expected to have
called Py_Initialize() and usually PyEval_InitThreads().
*/
- assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
- tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
+ assert(interp);
+ tcur = (PyThreadState *)PyThread_get_key_value(interp->auto_tls_key);
if (tcur == NULL) {
/* Create a new thread state for this thread */
- tcur = PyThreadState_New(autoInterpreterState);
+ tcur = PyThreadState_New(interp);
if (tcur == NULL)
Py_FatalError("Couldn't create thread-state for new thread");
/* This is our thread state! We'll need to delete it in the
@@ -664,11 +667,17 @@
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
}
+PyGILState_STATE
+PyGILState_Ensure()
+{
+ return PyGILState_EnsureEx(main_interp);
+}
+
void
-PyGILState_Release(PyGILState_STATE oldstate)
+PyGILState_ReleaseEx(PyInterpreterState *interp, PyGILState_STATE oldstate)
{
PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
- autoTLSkey);
+ interp->auto_tls_key);
if (tcur == NULL)
Py_FatalError("auto-releasing thread-state, "
"but no thread-state for this thread");
@@ -679,7 +688,6 @@
*/
if (! PyThreadState_IsCurrent(tcur))
Py_FatalError("This thread state must be current when releasing");
- assert(PyThreadState_IsCurrent(tcur));
--tcur->gilstate_counter;
assert(tcur->gilstate_counter >= 0); /* illegal counter value */
@@ -702,6 +710,12 @@
PyEval_SaveThread();
}
+void
+PyGILState_Release(PyGILState_STATE oldstate)
+{
+ PyGILState_ReleaseEx(main_interp, oldstate);
+}
+
#ifdef __cplusplus
}
#endif
« no previous file with comments | « Modules/_threadmodule.c ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+