##// END OF EJS Templates
Kernel subprocess parent polling is now implemented correctly for Unix.
epatters -
Show More
@@ -348,22 +348,35 b' class Kernel(object):'
348 # Kernel main and launch functions
348 # Kernel main and launch functions
349 #-----------------------------------------------------------------------------
349 #-----------------------------------------------------------------------------
350
350
351 class UnixPoller(Thread):
351 class ExitPollerUnix(Thread):
352 """ A Unix-specific daemon thread that terminates the program immediately
353 when this process' parent process no longer exists.
354 """
352
355
353 def __init__(self):
356 def __init__(self):
354 super(UnixPoller, self).__init__()
357 super(ExitPollerUnix, self).__init__()
355 self.daemon = True
358 self.daemon = True
356
359
357 def run(self):
360 def run(self):
361 # We cannot use os.waitpid because it works only for child processes.
362 from errno import EINTR
358 while True:
363 while True:
359 if os.getppid() == 1:
364 try:
360 os._exit(1)
365 if os.getppid() == 1:
361 time.sleep(5.0)
366 os._exit(1)
362
367 time.sleep(1.0)
363 class WindowsPoller(Thread):
368 except OSError, e:
369 if e.errno == EINTR:
370 continue
371 raise
372
373 class ExitPollerWindows(Thread):
374 """ A Windows-specific daemon thread that terminates the program immediately
375 when a Win32 handle is signaled.
376 """
364
377
365 def __init__(self, handle):
378 def __init__(self, handle):
366 super(WindowsPoller, self).__init__()
379 super(ExitPollerWindows, self).__init__()
367 self.daemon = True
380 self.daemon = True
368 self.handle = handle
381 self.handle = handle
369
382
@@ -373,6 +386,7 b' class WindowsPoller(Thread):'
373 if result == WAIT_OBJECT_0:
386 if result == WAIT_OBJECT_0:
374 os._exit(1)
387 os._exit(1)
375
388
389
376 def bind_port(socket, ip, port):
390 def bind_port(socket, ip, port):
377 """ Binds the specified ZMQ socket. If the port is less than zero, a random
391 """ Binds the specified ZMQ socket. If the port is less than zero, a random
378 port is chosen. Returns the port that was bound.
392 port is chosen. Returns the port that was bound.
@@ -385,6 +399,7 b' def bind_port(socket, ip, port):'
385 socket.bind(connection)
399 socket.bind(connection)
386 return port
400 return port
387
401
402
388 def main():
403 def main():
389 """ Main entry point for launching a kernel.
404 """ Main entry point for launching a kernel.
390 """
405 """
@@ -435,17 +450,11 b' def main():'
435
450
436 # Configure this kernel/process to die on parent termination, if necessary.
451 # Configure this kernel/process to die on parent termination, if necessary.
437 if namespace.parent:
452 if namespace.parent:
438 if sys.platform == 'linux2':
453 if sys.platform == 'win32':
439 import ctypes, ctypes.util, signal
454 poller = ExitPollerWindows(namespace.parent)
440 PR_SET_PDEATHSIG = 1
441 libc = ctypes.CDLL(ctypes.util.find_library('c'))
442 libc.prctl(PR_SET_PDEATHSIG, signal.SIGKILL)
443 elif sys.platform == 'win32':
444 poller = WindowsPoller(namespace.parent)
445 poller.start()
446 else:
455 else:
447 poller = UnixPoller()
456 poller = ExitPollerUnix()
448 poller.start()
457 poller.start()
449
458
450 # Start the kernel mainloop.
459 # Start the kernel mainloop.
451 kernel.start()
460 kernel.start()
@@ -448,6 +448,7 b' class KernelManager(HasTraits):'
448
448
449 def __init__(self, xreq_address=None, sub_address=None, rep_address=None,
449 def __init__(self, xreq_address=None, sub_address=None, rep_address=None,
450 context=None, session=None):
450 context=None, session=None):
451 super(KernelManager, self).__init__()
451 self._xreq_address = (LOCALHOST, 0) if xreq_address is None else xreq_address
452 self._xreq_address = (LOCALHOST, 0) if xreq_address is None else xreq_address
452 self._sub_address = (LOCALHOST, 0) if sub_address is None else sub_address
453 self._sub_address = (LOCALHOST, 0) if sub_address is None else sub_address
453 self._rep_address = (LOCALHOST, 0) if rep_address is None else rep_address
454 self._rep_address = (LOCALHOST, 0) if rep_address is None else rep_address
General Comments 0
You need to be logged in to leave comments. Login now