mirror of https://github.com/python/cpython
apply Mark Hammond's PEP 311 changes to the EMX ripoff of the Windows
popen[234]() code
This commit is contained in:
parent
75e0145bb5
commit
baf25b06a6
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue