From 25059d30c39c0c703161987643f0c29df03147fb Mon Sep 17 00:00:00 2001
From: Tim Peters <tim.peters@gmail.com>
Date: Fri, 7 Dec 2001 20:35:43 +0000
Subject: [PATCH] SF patch #489173:  Make os.spawnv not block the interpreter,
 from Anthony Roach. Release the global interpreter lock around platform spawn
 calls. Bugfix candidate?  Hard to say; I favor "yes, bugfix". These clearly
 *should* have been releasing the GIL all along, if for no other reason than
 compatibility with the similar os.system().  But it's possible some program
 out there is (a) multithreaded, (b) calling a spawn function with P_WAIT, and
 (c) relying on the spawn call to block all their threads until the spawned
 program completes.  I think it's very unlikely anyone is doing that on
 purpose, but someone may be doing so by accident.

---
 Misc/ACKS             |  1 +
 Misc/NEWS             |  7 +++++++
 Modules/posixmodule.c | 13 ++++++++++---
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/Misc/ACKS b/Misc/ACKS
index 1ee3f0c9d0..e110f15ee6 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -353,6 +353,7 @@ Jan Pieter Riegel
 Armin Rigo
 Nicholas Riley
 Jean-Claude Rimbault
+Anthony Roach
 Andy Robinson
 Jim Robinson
 Kevin Rodgers
diff --git a/Misc/NEWS b/Misc/NEWS
index 6dd99579fc..6df0b52041 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -52,6 +52,13 @@ Extension modules
 
 Library
 
+- Functions in the os.spawn() family now release the global interpreter
+  lock around calling the platform spawn.  They should always have done
+  this, but did not before 2.2c1.  Multithreaded programs calling
+  an os.spawn function with P_WAIT will no longer block all Python threads
+  until the spawned program completes.  It's possible that some programs
+  relies on blocking, although more likely by accident than by design.
+
 - webbrowser defaults to netscape.exe on OS/2 now.
 
 - Tix.ResizeHandle exposes detach_widget, hide, and show.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index bb557626ba..ebda8bf909 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1668,7 +1668,7 @@ posix_execve(PyObject *self, PyObject *args)
 #ifdef HAVE_SPAWNV
 static char posix_spawnv__doc__[] =
 "spawnv(mode, path, args)\n\
-Execute an executable path with arguments, replacing current process.\n\
+Execute the program 'path' in a new process.\n\
 \n\
 	mode: mode of process creation\n\
 	path: path of executable file\n\
@@ -1717,8 +1717,11 @@ posix_spawnv(PyObject *self, PyObject *args)
 
 	if (mode == _OLD_P_OVERLAY)
 		mode = _P_OVERLAY;
+	
+	Py_BEGIN_ALLOW_THREADS
 	spawnval = _spawnv(mode, path, argvlist);
-
+	Py_END_ALLOW_THREADS
+	
 	PyMem_DEL(argvlist);
 
 	if (spawnval == -1)
@@ -1734,7 +1737,7 @@ posix_spawnv(PyObject *self, PyObject *args)
 
 static char posix_spawnve__doc__[] =
 "spawnve(mode, path, args, env)\n\
-Execute a path with arguments and environment, replacing current process.\n\
+Execute the program 'path' in a new process.\n\
 \n\
 	mode: mode of process creation\n\
 	path: path of executable file\n\
@@ -1830,7 +1833,11 @@ posix_spawnve(PyObject *self, PyObject *args)
 
 	if (mode == _OLD_P_OVERLAY)
 		mode = _P_OVERLAY;
+
+	Py_BEGIN_ALLOW_THREADS
 	spawnval = _spawnve(mode, path, argvlist, envlist);
+	Py_END_ALLOW_THREADS
+
 	if (spawnval == -1)
 		(void) posix_error();
 	else
-- 
2.18.1