changeset 10238:e22695b4472f

cmdutil: replace unix pipe handshake with file lock The pipe handshake cannot be implemented with Windows detached process, which disables handle inheritance. Fix 2/3 for issue421
author Patrick Mezard <pmezard@gmail.com>
date Wed, 06 Jan 2010 21:11:58 +0100
parents 2f7a38f336f4
children 8e4be44a676f
files mercurial/cmdutil.py
diffstat 1 files changed, 28 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Fri Apr 10 21:20:25 2009 +0200
+++ b/mercurial/cmdutil.py	Wed Jan 06 21:11:58 2010 +0100
@@ -7,7 +7,7 @@
 
 from node import hex, nullid, nullrev, short
 from i18n import _
-import os, sys, errno, re, glob
+import os, sys, errno, re, glob, tempfile, time
 import mdiff, bdiff, util, templater, patch, error, encoding, templatekw
 import match as _match
 
@@ -567,22 +567,31 @@
     '''Run a command as a service.'''
 
     if opts['daemon'] and not opts['daemon_pipefds']:
-        rfd, wfd = os.pipe()
-        if not runargs:
-            runargs = sys.argv[:]
-        runargs.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
-        # Don't pass --cwd to the child process, because we've already
-        # changed directory.
-        for i in xrange(1,len(runargs)):
-            if runargs[i].startswith('--cwd='):
-                del runargs[i]
-                break
-            elif runargs[i].startswith('--cwd'):
-                del runargs[i:i+2]
-                break
-        pid = util.spawndetached(runargs)
-        os.close(wfd)
-        os.read(rfd, 1)
+        # Signal child process startup with file removal
+        lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
+        os.close(lockfd)        
+        try:
+            if not runargs:
+                runargs = sys.argv[:]
+            runargs.append('--daemon-pipefds=%s' % lockpath)
+            # Don't pass --cwd to the child process, because we've already
+            # changed directory.
+            for i in xrange(1,len(runargs)):
+                if runargs[i].startswith('--cwd='):
+                    del runargs[i]
+                    break
+                elif runargs[i].startswith('--cwd'):
+                    del runargs[i:i+2]
+                    break
+            pid = util.spawndetached(runargs)  
+            while os.path.exists(lockpath):
+                time.sleep(0.1)
+        finally:
+            try:
+                os.unlink(lockpath)
+            except OSError, e:
+                if e.errno != errno.ENOENT:
+                    raise
         if parentfn:
             return parentfn(pid)
         else:
@@ -598,14 +607,12 @@
         fp.close()
 
     if opts['daemon_pipefds']:
-        rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
-        os.close(rfd)
+        lockpath = opts['daemon_pipefds']
         try:
             os.setsid()
         except AttributeError:
             pass
-        os.write(wfd, 'y')
-        os.close(wfd)
+        os.unlink(lockpath)
         sys.stdout.flush()
         sys.stderr.flush()