apply Mark Hammond's PEP 311 changes to the EMX ripoff of the Windows

popen[234]() code
This commit is contained in:
Andrew MacIntyre 2003-04-21 14:22:36 +00:00
parent 75e0145bb5
commit baf25b06a6
1 changed files with 6 additions and 51 deletions

View 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;
}