[Python-checkins] python/dist/src/Modules _testcapimodule.c,1.21,1.22 posixmodule.c,2.294,2.295

mhammond@users.sourceforge.net mhammond@users.sourceforge.net
2003年4月19日 08:42:20 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv30725/Modules
Modified Files:
	_testcapimodule.c posixmodule.c 
Log Message:
New PyGILState_ API - implements pep 311, from patch 684256.
Index: _testcapimodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** _testcapimodule.c	17 Apr 2003 18:55:25 -0000	1.21
--- _testcapimodule.c	19 Apr 2003 15:41:47 -0000	1.22
***************
*** 8,11 ****
--- 8,15 ----
 #include "Python.h"
 
+ #ifdef WITH_THREAD
+ #include "pythread.h"
+ #endif /* WITH_THREAD */
+ 
 static PyObject *TestError;	/* set to exception object in init */
 
***************
*** 536,539 ****
--- 540,583 ----
 }
 
+ #ifdef WITH_THREAD
+ 
+ void _make_call(void *callable)
+ {
+ 	PyObject *rc;
+ 	PyGILState_STATE s = PyGILState_Ensure();
+ 	rc = PyObject_CallFunction(callable, "");
+ 	Py_XDECREF(rc);
+ 	PyGILState_Release(s);
+ }
+ 
+ static PyObject *
+ test_thread_state(PyObject *self, PyObject *args)
+ {
+ 	PyObject *fn;
+ 	if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn))
+ 		return NULL;
+ 	/* Ensure Python is setup for threading */
+ 	PyEval_InitThreads();
+ 	/* Start a new thread for our callback. */
+ 	PyThread_start_new_thread( _make_call, fn);
+ 	/* Make the callback with the thread lock held by this thread */
+ 	_make_call(fn);
+ 	/* Do it all again, but this time with the thread-lock released */
+ 	Py_BEGIN_ALLOW_THREADS
+ 	_make_call(fn);
+ 	Py_END_ALLOW_THREADS
+ 	/* And once more with and without a thread
+ 	 XXX - should use a lock and work out exactly what we are trying 
+ 	 to test <wink> 
+ 	*/
+ 	Py_BEGIN_ALLOW_THREADS
+ 	PyThread_start_new_thread( _make_call, fn);
+ 	_make_call(fn);
+ 	Py_END_ALLOW_THREADS
+ 	Py_INCREF(Py_None);
+ 	return Py_None;
+ }
+ #endif
+ 
 static PyMethodDef TestMethods[] = {
 	{"raise_exception",	raise_exception,		 METH_VARARGS},
***************
*** 554,557 ****
--- 598,604 ----
 #ifdef Py_USING_UNICODE
 	{"test_u_code",		(PyCFunction)test_u_code,	 METH_NOARGS},
+ #endif
+ #ifdef WITH_THREAD
+ 	{"_test_thread_state", (PyCFunction)test_thread_state, METH_VARARGS},
 #endif
 	{NULL, NULL} /* sentinel */
Index: posixmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v
retrieving revision 2.294
retrieving revision 2.295
diff -C2 -d -r2.294 -r2.295
*** posixmodule.c	29 Mar 2003 10:04:54 -0000	2.294
--- posixmodule.c	19 Apr 2003 15:41:47 -0000	2.295
***************
*** 4355,4374 ****
 * files to be closed in any order - it is always the close() of the
 * final handle that will return the exit code.
 */
 
- /* RED_FLAG 31-Aug-2000 Tim
- * This is always called (today!) between a pair of
- * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
- * macros. So the thread running this has no valid thread state, as
- * far as Python is concerned. However, this calls some Python API
- * functions that cannot be called safely without a valid thread
- * state, in particular PyDict_GetItem.
- * As a temporary hack (although it may last for years ...), we
- * *rely* on not having a valid thread state in this function, in
- * order to create our own "from scratch".
- * This will deadlock if _PyPclose is ever called by a thread
- * holding the global lock.
- */
- 
 static int _PyPclose(FILE *file)
 {
--- 4355,4363 ----
 * files to be closed in any order - it is always the close() of the
 * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
 */
 
 static int _PyPclose(FILE *file)
 {
***************
*** 4379,4384 ****
 	long file_count;
 #ifdef WITH_THREAD
! 	PyInterpreterState* pInterpreterState;
! 	PyThreadState* pThreadState;
 #endif
 
--- 4368,4372 ----
 	long file_count;
 #ifdef WITH_THREAD
! 	PyGILState_STATE state;
 #endif
 
***************
*** 4387,4416 ****
 	 */
 	result = fclose(file);
- 
 #ifdef WITH_THREAD
! 	/* Bootstrap a valid thread state into existence. */
! 	pInterpreterState = PyInterpreterState_New();
! 	if (!pInterpreterState) {
! 		/* Well, we're hosed now! We don't have a thread
! 		 * state, so can't call a nice error routine, or raise
! 		 * an exception. Just die.
! 		 */
! 		 Py_FatalError("unable to allocate interpreter state "
! 		 	 "when closing popen object");
! 		 return -1; /* unreachable */
! 	}
! 	pThreadState = PyThreadState_New(pInterpreterState);
! 	if (!pThreadState) {
! 		 Py_FatalError("unable to allocate thread state "
! 		 	 "when closing popen object");
! 		 return -1; /* unreachable */
! 	}
! 	/* Grab the global lock. Note that this will deadlock if the
! 	 * current thread already has the lock! (see RED_FLAG comments
! 	 * before this function)
! 	 */
! 	PyEval_RestoreThread(pThreadState);
 #endif
- 
 	if (_PyPopenProcs) {
 		if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
--- 4375,4381 ----
 	 */
 	result = fclose(file);
 #ifdef WITH_THREAD
! 	state = PyGILState_Ensure();
 #endif
 	if (_PyPopenProcs) {
 		if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
***************
*** 4471,4485 ****
 
 #ifdef WITH_THREAD
! 	/* Tear down the thread & interpreter states.
! 	 * Note that interpreter state clear & delete functions automatically
! 	 * call the thread clear & delete functions, and indeed insist on
! 	 * doing that themselves. The lock must be held during the clear, but
! 	 * need not be held during the delete.
! 	 */
! 	PyInterpreterState_Clear(pInterpreterState);
! 	PyEval_ReleaseThread(pThreadState);
! 	PyInterpreterState_Delete(pInterpreterState);
 #endif
- 
 	return result;
 }
--- 4436,4441 ----
 
 #ifdef WITH_THREAD
! 	PyGILState_Release(state);
 #endif
 	return result;
 }

AltStyle によって変換されたページ (->オリジナル) /