[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
Sat, 19 Apr 2003 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;
}