[Python-Dev] Threaded Cygwin Python Import Problem

Jason Tishler Jason.Tishler@dothill.com
Thu, 28 Jun 2001 17:17:15 -0400

Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Thanks to Rob Collins (implementer) and Greg Smith (profiler), Cygwin now
provides enough pthreads support so that Cygwin Python builds OOTB *and*
functions reasonably well even with threads enabled.  Unfortunately,
there are still a few issues that need to be resolved.

The one that I would like to address in this posting prevents a threaded
Cygwin Python from building the standard extension modules (without some
kind of intervention).  :,(  Specifically, the build would frequently
hang during the Distutils part when Cygwin Python is attempting to execvp
a gcc process.

See the first attachment, test.py, for a minimal Python script that
exhibits the hang.  See the second attachment, test.c, for a rewrite
of test.py in C.  Since test.c did not hang, I was able to conclude that
this was not just a straight Cygwin problem.

Further tracing uncovered that the hang occurs in _execvpe() (in os.py),
when the child tries to import tempfile.  If I apply the third attachment,
os.py.patch, then the hang is avoided.  Hence, it appears that importing a
module (or specifically the tempfile module) in a threaded Cygwin Python
child cause a hang.

I saw the following comment in _execvpe():

    #  Process handling (fork, wait) under BeOS (up to 5.0)
    #  doesn't interoperate reliably with the thread interlocking
    #  that happens during an import.  The actual error we need
    #  is the same on BeOS for posix.open() et al., ENOENT.

The above makes me think that possibly Cygwin is having a similar problem.

Can anyone offer suggestions on how to further debug this problem?


Jason Tishler
Director, Software Engineering       Phone: 732.264.8770 x235
Dot Hill Systems Corp.               Fax:   732.264.8798
82 Bethany Road, Suite 7             Email: Jason.Tishler@dothill.com
Hazlet, NJ 07730 USA                 WWW:   http://www.dothill.com

Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test.py"

import os

cmd = ['ls', '-l']

pid = os.fork()

if pid == 0:
	print 'child execvp-ing'
	os.execvp(cmd[0], cmd)
	(pid, status) = os.waitpid(pid, 0)
	print 'status =', status
	print 'parent done'

Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test.c"

#include <unistd.h>
#include <sys/wait.h>

char* const cmd[] = {"ls", "-l", 0};

	int status;

	pid_t pid = fork();
	if (pid == 0)
		printf("child execvp-ing\n");
		execvp(cmd[0], cmd);
		waitpid(pid, &status, 0);
		printf("status = %d\n", status);
		printf("parent done\n");

Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="os.py.patch"

--- os.py.orig	Thu Jun 28 16:14:28 2001
+++ os.py	Thu Jun 28 16:30:12 2001
@@ -329,8 +329,9 @@ def _execvpe(file, args, env=None):
             try: unlink('/_#.# ## #.#')
             except error, _notfound: pass
-            import tempfile
-            t = tempfile.mktemp()
+            #import tempfile
+            #t = tempfile.mktemp()
+            t = '/mnt/c/TEMP/@279.3'
             # Exec a file that is guaranteed not to exist
             try: execv(t, ('blah',))
             except error, _notfound: pass