[Python-checkins] python/dist/src/Python pystate.c, 2.38.2.2, 2.38.2.3

mwh@users.sourceforge.net mwh at users.sourceforge.net
Fri Sep 23 10:14:43 CEST 2005


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7459/Python

Modified Files:
      Tag: release24-maint
	pystate.c 
Log Message:
Backport bugfix:

Fix bug: 

[ 1163563 ] Sub threads execute in restricted mode 

basically by fixing bug 1010677 in a non-broken way. 

Backport candidate. 



Index: pystate.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v
retrieving revision 2.38.2.2
retrieving revision 2.38.2.3
diff -u -d -r2.38.2.2 -r2.38.2.3
--- pystate.c	24 Apr 2005 19:32:34 -0000	2.38.2.2
+++ pystate.c	23 Sep 2005 08:14:40 -0000	2.38.2.3
@@ -36,6 +36,12 @@
 #define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
 #define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
 #define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
+
+/* The single PyInterpreterState used by this process'
+   GILState implementation
+*/
+static PyInterpreterState *autoInterpreterState = NULL;
+static int autoTLSkey = 0;
 #else
 #define HEAD_INIT() /* Nothing */
 #define HEAD_LOCK() /* Nothing */
@@ -47,6 +53,8 @@
 PyThreadState *_PyThreadState_Current = NULL;
 PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
 
+static void _PyGILState_NoteThreadState(PyThreadState* tstate);
+
 
 PyInterpreterState *
 PyInterpreterState_New(void)
@@ -180,6 +188,8 @@
 		tstate->c_profileobj = NULL;
 		tstate->c_traceobj = NULL;
 
+		_PyGILState_NoteThreadState(tstate);
+
 		HEAD_LOCK();
 		tstate->next = interp->tstate_head;
 		interp->tstate_head = tstate;
@@ -261,6 +271,8 @@
 			"PyThreadState_DeleteCurrent: no current tstate");
 	_PyThreadState_Current = NULL;
 	tstate_delete_common(tstate);
+	if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+		PyThread_delete_key_value(autoTLSkey);
 	PyEval_ReleaseLock();
 }
 #endif /* WITH_THREAD */
@@ -393,12 +405,6 @@
 	return tstate == _PyThreadState_Current;
 }
 
-/* The single PyInterpreterState used by this process'
-   GILState implementation
-*/
-static PyInterpreterState *autoInterpreterState = NULL;
-static int autoTLSkey = 0;
-
 /* Internal initialization/finalization functions called by
    Py_Initialize/Py_Finalize
 */
@@ -408,12 +414,10 @@
 	assert(i && t); /* must init with valid states */
 	autoTLSkey = PyThread_create_key();
 	autoInterpreterState = i;
-	/* Now stash the thread state for this thread in TLS */
 	assert(PyThread_get_key_value(autoTLSkey) == NULL);
-	if (PyThread_set_key_value(autoTLSkey, (void *)t) < 0)
-		Py_FatalError("Couldn't create autoTLSkey mapping");
-	assert(t->gilstate_counter == 0); /* must be a new thread state */
-	t->gilstate_counter = 1;
+	assert(t->gilstate_counter == 0);
+
+	_PyGILState_NoteThreadState(t);
 }
 
 void
@@ -424,6 +428,41 @@
 	autoInterpreterState = NULL;;
 }
 
+/* When a thread state is created for a thread by some mechanism other than
+   PyGILState_Ensure, it's important that the GILState machinery knows about
+   it so it doesn't try to create another thread state for the thread (this is
+   a better fix for SF bug #1010677 than the first one attempted).
+*/
+void
+_PyGILState_NoteThreadState(PyThreadState* tstate)
+{
+	/* If autoTLSkey is 0, 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 (!autoTLSkey) 
+		return;
+	
+	/* Stick the thread state for this thread in thread local storage.
+
+	   The only situation where you can legitimately have more than one
+	   thread state for an OS level thread is when there are multiple
+	   interpreters, when:
+	       
+	       a) You shouldn't really be using the PyGILState_ APIs anyway,
+	          and:
+
+	       b) The slightly odd way PyThread_set_key_value works (see
+	          comments by its implementation) means that the first thread
+	          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");
+
+	/* PyGILState_Release must not try to delete this thread state. */
+	tstate->gilstate_counter = 1;
+}
+
 /* The public functions */
 PyThreadState *
 PyGILState_GetThisThreadState(void)
@@ -450,8 +489,9 @@
 		tcur = PyThreadState_New(autoInterpreterState);
 		if (tcur == NULL)
 			Py_FatalError("Couldn't create thread-state for new thread");
-		if (PyThread_set_key_value(autoTLSkey, (void *)tcur) < 0)
-			Py_FatalError("Couldn't create autoTLSkey mapping");
+		/* This is our thread state!  We'll need to delete it in the
+		   matching call to PyGILState_Release(). */
+		tcur->gilstate_counter = 0;
 		current = 0; /* new thread state is never current */
 	}
 	else
@@ -498,8 +538,6 @@
 		 * habit of coming back).
 		 */
 		PyThreadState_DeleteCurrent();
-		/* Delete this thread from our TLS. */
-		PyThread_delete_key_value(autoTLSkey);
 	}
 	/* Release the lock if necessary */
 	else if (oldstate == PyGILState_UNLOCKED)



More information about the Python-checkins mailing list