[PATCH 2 of 4] cmdutil: replace unix pipe handshake with file lock
Patrick Mezard
pmezard at gmail.com
Sun Jan 10 17:33:01 UTC 2010
# HG changeset patch
# User Patrick Mezard <pmezard at gmail.com>
# Date 1262808718 -3600
# Node ID 5b7842ed06260749364e7f71dc1fcf6f6df653d2
# Parent 46c105dcbc105bd9fed00adb38f92dbba4e4a883
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
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -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, lock
import mdiff, bdiff, util, templater, patch, error, encoding, templatekw
import match as _match
@@ -567,22 +567,35 @@
'''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)
+ # Fake an already locked lock
+ lockfd, lockpath = tempfile.mkstemp()
+ os.close(lockfd)
+ os.unlink(lockpath)
+ util.makelock(str(os.getpid()+1), lockpath)
+
+ 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)
+ wlock = lock.lock(lockpath, sleep=0.1)
+ wlock.release()
+ finally:
+ try:
+ os.unlink(lockpath)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
if parentfn:
return parentfn(pid)
else:
@@ -598,14 +611,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()
diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -29,13 +29,14 @@
_host = None
- def __init__(self, file, timeout=-1, releasefn=None, desc=None):
+ def __init__(self, file, timeout=-1, releasefn=None, desc=None,
+ sleep=1):
self.f = file
self.held = 0
self.timeout = timeout
self.releasefn = releasefn
self.desc = desc
- self.lock()
+ self.lock(sleep=sleep)
def __del__(self):
if self.held:
@@ -49,7 +50,7 @@
self.release()
- def lock(self):
+ def lock(self, sleep=1):
timeout = self.timeout
while 1:
try:
@@ -57,7 +58,7 @@
return 1
except error.LockHeld, inst:
if timeout != 0:
- time.sleep(1)
+ time.sleep(sleep)
if timeout > 0:
timeout -= 1
continue
More information about the Mercurial-devel
mailing list