Mercurial > public > mercurial-scm > hg
comparison mercurial/worker.py @ 31063:18fb3cf572b4 stable
worker: ignore meaningless exit status indication returned by os.waitpid()
Before this patch, worker implementation assumes that os.waitpid()
with os.WNOHANG returns '(0, 0)' for still running child process. This
is explicitly specified as below in Python API document.
os.WNOHANG
The option for waitpid() to return immediately if no child
process status is available immediately. The function returns
(0, 0) in this case.
On the other hand, POSIX specification doesn't define the "stat_loc"
value returned by waitpid() with WNOHANG for such child process.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html
CPython implementation for os.waitpid() on POSIX doesn't take any care
of this gap, and this may cause unexpected "exit status indication"
even on POSIX conformance platform.
For example, os.waitpid() with os.WNOHANG returns non-zero "exit
status indication" on FreeBSD. This implies os.kill() with own pid or
sys.exit() with non-zero exit code, even if no child process fails.
To ignore meaningless exit status indication returned by os.waitpid(),
this patch skips subsequent steps forcibly, if os.waitpid() returns 0
as pid.
This patch also arranges examination of 'p' value for readability.
FYI, there are some issues below about this behavior reported for
CPython.
https://bugs.python.org/issue21791
https://bugs.python.org/issue27808
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Sat, 25 Feb 2017 01:07:52 +0900 |
parents | d524c88511a7 |
children | a91c62752d08 |
comparison
equal
deleted
inserted
replaced
30915:aa25989b0658 | 31063:18fb3cf572b4 |
---|---|
118 # updated (maybe interrupted just after waitpid) | 118 # updated (maybe interrupted just after waitpid) |
119 pids.discard(pid) | 119 pids.discard(pid) |
120 break | 120 break |
121 else: | 121 else: |
122 raise | 122 raise |
123 if p: | 123 if not p: |
124 pids.discard(p) | 124 # skip subsequent steps, because child process should |
125 st = _exitstatus(st) | 125 # be still running in this case |
126 continue | |
127 pids.discard(p) | |
128 st = _exitstatus(st) | |
126 if st and not problem[0]: | 129 if st and not problem[0]: |
127 problem[0] = st | 130 problem[0] = st |
128 def sigchldhandler(signum, frame): | 131 def sigchldhandler(signum, frame): |
129 waitforworkers(blocking=False) | 132 waitforworkers(blocking=False) |
130 if problem[0]: | 133 if problem[0]: |