]> granicus.if.org Git - python/commitdiff
apply Mark Hammond's PEP 311 changes to the EMX ripoff of the Windows
authorAndrew MacIntyre <andymac@bullseye.apana.org.au>
Mon, 21 Apr 2003 14:22:36 +0000 (14:22 +0000)
committerAndrew MacIntyre <andymac@bullseye.apana.org.au>
Mon, 21 Apr 2003 14:22:36 +0000 (14:22 +0000)
popen[234]() code

Modules/posixmodule.c

index 879d57e8eeeb1d9dd3e1ae8cbb045ea0d85cf677..86162c21877fcde45ad00514476e6f1106fdee14 100644 (file)
@@ -3556,24 +3556,11 @@ _PyPopen(char *cmdstring, int mode, int n, int bufsize)
  * exit code as the result of the close() operation.  This permits the
  * 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.
  */
 
- /* 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.
-  * (The OS/2 EMX thread support appears to cover the case where the
-  *  lock is already held - AIM Apr01)
-  */
-
 static int _PyPclose(FILE *file)
 {
        int result;
@@ -3582,8 +3569,7 @@ static int _PyPclose(FILE *file)
        PyObject *procObj, *pidObj, *intObj, *fileObj;
        int file_count;
 #ifdef WITH_THREAD
-       PyInterpreterState* pInterpreterState;
-       PyThreadState* pThreadState;
+       PyGILState_STATE state;
 #endif
 
        /* Close the file handle first, to ensure it can't block the
@@ -3592,30 +3578,8 @@ static int _PyPclose(FILE *file)
        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);
+       state = PyGILState_Ensure();
 #endif
-
        if (_PyPopenProcs)
        {
                if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
@@ -3678,17 +3642,8 @@ static int _PyPclose(FILE *file)
        } /* if _PyPopenProcs */
 
 #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);
+       PyGILState_Release(state);
 #endif
-
        return result;
 }