@@ -4354,22 +4354,11 @@ _PyPopen(char *cmdstring, int mode, int n)
43544354 * exit code as the result of the close() operation.  This permits the 
43554355 * files to be closed in any order - it is always the close() of the 
43564356 * final handle that will return the exit code. 
4357+  * 
4358+  * NOTE: This function is currently called with the GIL released. 
4359+  * hence we use the GILState API to manage our state. 
43574360 */ 
43584361
4359-  /* RED_FLAG 31-Aug-2000 Tim 
4360-   * This is always called (today!) between a pair of 
4361-   * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS 
4362-   * macros.  So the thread running this has no valid thread state, as 
4363-   * far as Python is concerned.  However, this calls some Python API 
4364-   * functions that cannot be called safely without a valid thread 
4365-   * state, in particular PyDict_GetItem. 
4366-   * As a temporary hack (although it may last for years ...), we 
4367-   * *rely* on not having a valid thread state in this function, in 
4368-   * order to create our own "from scratch". 
4369-   * This will deadlock if _PyPclose is ever called by a thread 
4370-   * holding the global lock. 
4371-   */ 
4372- 
43734362static  int  _PyPclose (FILE  * file )
43744363{
43754364	int  result ;
@@ -4378,40 +4367,16 @@ static int _PyPclose(FILE *file)
43784367	PyObject  * procObj , * hProcessObj , * intObj , * fileObj ;
43794368	long  file_count ;
43804369#ifdef  WITH_THREAD 
4381- 	PyInterpreterState *  pInterpreterState ;
4382- 	PyThreadState *  pThreadState ;
4370+ 	PyGILState_STATE  state ;
43834371#endif 
43844372
43854373	/* Close the file handle first, to ensure it can't block the 
43864374	 * child from exiting if it's the last handle. 
43874375	 */ 
43884376	result  =  fclose (file );
4389- 
43904377#ifdef  WITH_THREAD 
4391- 	/* Bootstrap a valid thread state into existence. */ 
4392- 	pInterpreterState  =  PyInterpreterState_New ();
4393- 	if  (!pInterpreterState ) {
4394- 		/* Well, we're hosed now!  We don't have a thread 
4395- 		 * state, so can't call a nice error routine, or raise 
4396- 		 * an exception.  Just die. 
4397- 		 */ 
4398- 		 Py_FatalError ("unable to allocate interpreter state " 
4399- 		 	       "when closing popen object" );
4400- 		 return  -1 ;  /* unreachable */ 
4401- 	}
4402- 	pThreadState  =  PyThreadState_New (pInterpreterState );
4403- 	if  (!pThreadState ) {
4404- 		 Py_FatalError ("unable to allocate thread state " 
4405- 		 	       "when closing popen object" );
4406- 		 return  -1 ;  /* unreachable */ 
4407- 	}
4408- 	/* Grab the global lock.  Note that this will deadlock if the 
4409- 	 * current thread already has the lock! (see RED_FLAG comments 
4410- 	 * before this function) 
4411- 	 */ 
4412- 	PyEval_RestoreThread (pThreadState );
4378+ 	state  =  PyGILState_Ensure ();
44134379#endif 
4414- 
44154380	if  (_PyPopenProcs ) {
44164381		if  ((fileObj  =  PyLong_FromVoidPtr (file )) !=  NULL  && 
44174382		    (procObj  =  PyDict_GetItem (_PyPopenProcs ,
@@ -4470,17 +4435,8 @@ static int _PyPclose(FILE *file)
44704435	} /* if _PyPopenProcs */ 
44714436
44724437#ifdef  WITH_THREAD 
4473- 	/* Tear down the thread & interpreter states. 
4474- 	 * Note that interpreter state clear & delete functions automatically 
4475- 	 * call the thread clear & delete functions, and indeed insist on 
4476- 	 * doing that themselves.  The lock must be held during the clear, but 
4477- 	 * need not be held during the delete. 
4478- 	 */ 
4479- 	PyInterpreterState_Clear (pInterpreterState );
4480- 	PyEval_ReleaseThread (pThreadState );
4481- 	PyInterpreterState_Delete (pInterpreterState );
4438+ 	PyGILState_Release (state );
44824439#endif 
4483- 
44844440	return  result ;
44854441}
44864442
0 commit comments