mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
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
1 changed files with 6 additions and 51 deletions
|
@ -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
|
* 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
|
* files to be closed in any order - it is always the close() of the
|
||||||
* final handle that will return the exit code.
|
* 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)
|
static int _PyPclose(FILE *file)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
@ -3582,8 +3569,7 @@ static int _PyPclose(FILE *file)
|
||||||
PyObject *procObj, *pidObj, *intObj, *fileObj;
|
PyObject *procObj, *pidObj, *intObj, *fileObj;
|
||||||
int file_count;
|
int file_count;
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyInterpreterState* pInterpreterState;
|
PyGILState_STATE state;
|
||||||
PyThreadState* pThreadState;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Close the file handle first, to ensure it can't block the
|
/* Close the file handle first, to ensure it can't block the
|
||||||
|
@ -3592,30 +3578,8 @@ static int _PyPclose(FILE *file)
|
||||||
result = fclose(file);
|
result = fclose(file);
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
/* Bootstrap a valid thread state into existence. */
|
state = PyGILState_Ensure();
|
||||||
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
|
#endif
|
||||||
|
|
||||||
if (_PyPopenProcs)
|
if (_PyPopenProcs)
|
||||||
{
|
{
|
||||||
if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
|
if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
|
||||||
|
@ -3678,17 +3642,8 @@ static int _PyPclose(FILE *file)
|
||||||
} /* if _PyPopenProcs */
|
} /* if _PyPopenProcs */
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
/* Tear down the thread & interpreter states.
|
PyGILState_Release(state);
|
||||||
* 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
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue