Skip to content

Commit a6a4765

Browse files
committedJun 4, 2015
worker: wait for process termination
This prevents stray SIGCHLDs from crashing the program e.g. if the asyncio event loop is closed before the process actually terminates.
1 parent c843c35 commit a6a4765

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed
 

‎artiq/master/worker.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
from artiq.protocols import pyon
99
from artiq.language.units import strip_unit
10-
from artiq.tools import asyncio_process_wait_timeout, asyncio_wait_or_cancel
10+
from artiq.tools import (asyncio_process_wait_timeout, asyncio_process_wait,
11+
asyncio_wait_or_cancel)
1112

1213

1314
logger = logging.getLogger(__name__)
@@ -101,13 +102,15 @@ def close(self):
101102
logger.warning("failed to send terminate command to worker"
102103
" (RID %d), killing", self.rid, exc_info=True)
103104
self.process.kill()
105+
yield from asyncio_process_wait(self.process)
104106
return
105107
try:
106108
yield from asyncio_process_wait_timeout(self.process,
107109
self.term_timeout)
108110
except asyncio.TimeoutError:
109111
logger.warning("worker did not exit (RID %d), killing", self.rid)
110112
self.process.kill()
113+
yield from asyncio_process_wait(self.process)
111114
else:
112115
logger.debug("worker exited gracefully (RID %d)", self.rid)
113116
finally:

‎artiq/tools.py

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def parse_arguments(arguments):
1818
d[name] = pyon.decode(value)
1919
return d
2020

21+
2122
def format_arguments(arguments):
2223
fmtargs = []
2324
for k, v in sorted(arguments.items(), key=itemgetter(0)):
@@ -98,6 +99,14 @@ def asyncio_process_wait_timeout(process, timeout):
9899
timeout=end_time - time.monotonic())
99100

100101

102+
@asyncio.coroutine
103+
def asyncio_process_wait(process):
104+
r = True
105+
while r:
106+
f, p = yield from asyncio.wait([process.stdout.read(1024)])
107+
r = f.pop().result()
108+
109+
101110
@asyncio.coroutine
102111
def asyncio_wait_or_cancel(fs, **kwargs):
103112
fs = [asyncio.async(f) for f in fs]

0 commit comments

Comments
 (0)
Please sign in to comment.