##// 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 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 356 def __init__(self):
354 super(UnixPoller, self).__init__()
357 super(ExitPollerUnix, self).__init__()
355 358 self.daemon = True
356 359
357 360 def run(self):
361 # We cannot use os.waitpid because it works only for child processes.
362 from errno import EINTR
358 363 while True:
364 try:
359 365 if os.getppid() == 1:
360 366 os._exit(1)
361 time.sleep(5.0)
367 time.sleep(1.0)
368 except OSError, e:
369 if e.errno == EINTR:
370 continue
371 raise
362 372
363 class WindowsPoller(Thread):
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 378 def __init__(self, handle):
366 super(WindowsPoller, self).__init__()
379 super(ExitPollerWindows, self).__init__()
367 380 self.daemon = True
368 381 self.handle = handle
369 382
@@ -373,6 +386,7 b' class WindowsPoller(Thread):'
373 386 if result == WAIT_OBJECT_0:
374 387 os._exit(1)
375 388
389
376 390 def bind_port(socket, ip, port):
377 391 """ Binds the specified ZMQ socket. If the port is less than zero, a random
378 392 port is chosen. Returns the port that was bound.
@@ -385,6 +399,7 b' def bind_port(socket, ip, port):'
385 399 socket.bind(connection)
386 400 return port
387 401
402
388 403 def main():
389 404 """ Main entry point for launching a kernel.
390 405 """
@@ -435,16 +450,10 b' def main():'
435 450
436 451 # Configure this kernel/process to die on parent termination, if necessary.
437 452 if namespace.parent:
438 if sys.platform == 'linux2':
439 import ctypes, ctypes.util, signal
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()
453 if sys.platform == 'win32':
454 poller = ExitPollerWindows(namespace.parent)
446 455 else:
447 poller = UnixPoller()
456 poller = ExitPollerUnix()
448 457 poller.start()
449 458
450 459 # Start the kernel mainloop.
@@ -448,6 +448,7 b' class KernelManager(HasTraits):'
448 448
449 449 def __init__(self, xreq_address=None, sub_address=None, rep_address=None,
450 450 context=None, session=None):
451 super(KernelManager, self).__init__()
451 452 self._xreq_address = (LOCALHOST, 0) if xreq_address is None else xreq_address
452 453 self._sub_address = (LOCALHOST, 0) if sub_address is None else sub_address
453 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