Show More
@@ -584,9 +584,11 b' def service(opts, parentfn=None, initfn=' | |||||
584 | elif runargs[i].startswith('--cwd'): |
|
584 | elif runargs[i].startswith('--cwd'): | |
585 | del runargs[i:i + 2] |
|
585 | del runargs[i:i + 2] | |
586 | break |
|
586 | break | |
587 | pid = util.spawndetached(runargs) |
|
587 | def condfn(): | |
588 |
|
|
588 | return not os.path.exists(lockpath) | |
589 | time.sleep(0.1) |
|
589 | pid = util.rundetached(runargs, condfn) | |
|
590 | if pid < 0: | |||
|
591 | raise util.Abort(_('child process failed to start')) | |||
590 | finally: |
|
592 | finally: | |
591 | try: |
|
593 | try: | |
592 | os.unlink(lockpath) |
|
594 | os.unlink(lockpath) |
@@ -16,7 +16,7 b' hide platform-specific details from the ' | |||||
16 | from i18n import _ |
|
16 | from i18n import _ | |
17 | import error, osutil, encoding |
|
17 | import error, osutil, encoding | |
18 | import cStringIO, errno, re, shutil, sys, tempfile, traceback |
|
18 | import cStringIO, errno, re, shutil, sys, tempfile, traceback | |
19 | import os, stat, time, calendar, textwrap |
|
19 | import os, stat, time, calendar, textwrap, signal | |
20 | import imp |
|
20 | import imp | |
21 |
|
21 | |||
22 | # Python compatibility |
|
22 | # Python compatibility | |
@@ -1308,3 +1308,37 b' def hgcmd():' | |||||
1308 | if main_is_frozen(): |
|
1308 | if main_is_frozen(): | |
1309 | return [sys.executable] |
|
1309 | return [sys.executable] | |
1310 | return gethgcmd() |
|
1310 | return gethgcmd() | |
|
1311 | ||||
|
1312 | def rundetached(args, condfn): | |||
|
1313 | """Execute the argument list in a detached process. | |||
|
1314 | ||||
|
1315 | condfn is a callable which is called repeatedly and should return | |||
|
1316 | True once the child process is known to have started successfully. | |||
|
1317 | At this point, the child process PID is returned. If the child | |||
|
1318 | process fails to start or finishes before condfn() evaluates to | |||
|
1319 | True, return -1. | |||
|
1320 | """ | |||
|
1321 | # Windows case is easier because the child process is either | |||
|
1322 | # successfully starting and validating the condition or exiting | |||
|
1323 | # on failure. We just poll on its PID. On Unix, if the child | |||
|
1324 | # process fails to start, it will be left in a zombie state until | |||
|
1325 | # the parent wait on it, which we cannot do since we expect a long | |||
|
1326 | # running process on success. Instead we listen for SIGCHLD telling | |||
|
1327 | # us our child process terminated. | |||
|
1328 | terminated = set() | |||
|
1329 | def handler(signum, frame): | |||
|
1330 | terminated.add(os.wait()) | |||
|
1331 | prevhandler = None | |||
|
1332 | if hasattr(signal, 'SIGCHLD'): | |||
|
1333 | prevhandler = signal.signal(signal.SIGCHLD, handler) | |||
|
1334 | try: | |||
|
1335 | pid = spawndetached(args) | |||
|
1336 | while not condfn(): | |||
|
1337 | if ((pid in terminated or not testpid(pid)) | |||
|
1338 | and not condfn()): | |||
|
1339 | return -1 | |||
|
1340 | time.sleep(0.1) | |||
|
1341 | return pid | |||
|
1342 | finally: | |||
|
1343 | if prevhandler is not None: | |||
|
1344 | signal.signal(signal.SIGCHLD, prevhandler) |
@@ -1,6 +1,6 b'' | |||||
1 | % fail |
|
1 | % fail | |
2 | abort: inotify-server: cannot start: .hg/inotify.sock is a broken symlink |
|
2 | abort: inotify-server: cannot start: .hg/inotify.sock is a broken symlink | |
3 |
inotify-client: could not |
|
3 | inotify-client: could not start inotify server: child process failed to start | |
4 | abort: inotify-server: cannot start: .hg/inotify.sock is a broken symlink |
|
4 | abort: inotify-server: cannot start: .hg/inotify.sock is a broken symlink | |
5 | % inserve |
|
5 | % inserve | |
6 | % status |
|
6 | % status |
General Comments 0
You need to be logged in to leave comments.
Login now