##// END OF EJS Templates
Remove print statements in ZMQ parent pollers....
Evan Patterson -
Show More
@@ -1,125 +1,119
1 1 # Standard library imports.
2 2 import ctypes
3 3 import os
4 4 import time
5 5 from thread import interrupt_main
6 6 from threading import Thread
7 7
8 # Local imports.
9 from IPython.utils.io import raw_print
10
11 8
12 9 class ParentPollerUnix(Thread):
13 10 """ A Unix-specific daemon thread that terminates the program immediately
14 11 when the parent process no longer exists.
15 12 """
16 13
17 14 def __init__(self):
18 15 super(ParentPollerUnix, self).__init__()
19 16 self.daemon = True
20 17
21 18 def run(self):
22 19 # We cannot use os.waitpid because it works only for child processes.
23 20 from errno import EINTR
24 21 while True:
25 22 try:
26 23 if os.getppid() == 1:
27 raw_print('Killed by parent poller!')
28 24 os._exit(1)
29 25 time.sleep(1.0)
30 26 except OSError, e:
31 27 if e.errno == EINTR:
32 28 continue
33 29 raise
34 30
35 31
36 32 class ParentPollerWindows(Thread):
37 33 """ A Windows-specific daemon thread that listens for a special event that
38 34 signals an interrupt and, optionally, terminates the program immediately
39 35 when the parent process no longer exists.
40 36 """
41 37
42 38 def __init__(self, interrupt_handle=None, parent_handle=None):
43 39 """ Create the poller. At least one of the optional parameters must be
44 40 provided.
45 41
46 42 Parameters:
47 43 -----------
48 44 interrupt_handle : HANDLE (int), optional
49 45 If provided, the program will generate a Ctrl+C event when this
50 46 handle is signaled.
51 47
52 48 parent_handle : HANDLE (int), optional
53 49 If provided, the program will terminate immediately when this
54 50 handle is signaled.
55 51 """
56 52 assert(interrupt_handle or parent_handle)
57 53 super(ParentPollerWindows, self).__init__()
58 54 self.daemon = True
59 55 self.interrupt_handle = interrupt_handle
60 56 self.parent_handle = parent_handle
61 57
62 58 @staticmethod
63 59 def create_interrupt_event():
64 60 """ Create an interrupt event handle.
65 61
66 62 The parent process should use this static method for creating the
67 63 interrupt event that is passed to the child process. It should store
68 64 this handle and use it with ``send_interrupt`` to interrupt the child
69 65 process.
70 66 """
71 67 # Create a security attributes struct that permits inheritance of the
72 68 # handle by new processes.
73 69 # FIXME: We can clean up this mess by requiring pywin32 for IPython.
74 70 class SECURITY_ATTRIBUTES(ctypes.Structure):
75 71 _fields_ = [ ("nLength", ctypes.c_int),
76 72 ("lpSecurityDescriptor", ctypes.c_void_p),
77 73 ("bInheritHandle", ctypes.c_int) ]
78 74 sa = SECURITY_ATTRIBUTES()
79 75 sa_p = ctypes.pointer(sa)
80 76 sa.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
81 77 sa.lpSecurityDescriptor = 0
82 78 sa.bInheritHandle = 1
83 79
84 80 return ctypes.windll.kernel32.CreateEventA(
85 81 sa_p, # lpEventAttributes
86 82 False, # bManualReset
87 83 False, # bInitialState
88 84 '') # lpName
89 85
90 86 @staticmethod
91 87 def send_interrupt(interrupt_handle):
92 88 """ Sends an interrupt event using the specified handle.
93 89 """
94 90 ctypes.windll.kernel32.SetEvent(interrupt_handle)
95 91
96 92 def run(self):
97 93 """ Run the poll loop. This method never returns.
98 94 """
99 95 from _subprocess import WAIT_OBJECT_0, INFINITE
100 96
101 97 # Build the list of handle to listen on.
102 98 handles = []
103 99 if self.interrupt_handle:
104 100 handles.append(self.interrupt_handle)
105 101 if self.parent_handle:
106 102 handles.append(self.parent_handle)
107 103
108 104 # Listen forever.
109 105 while True:
110 106 result = ctypes.windll.kernel32.WaitForMultipleObjects(
111 107 len(handles), # nCount
112 108 (ctypes.c_int * len(handles))(*handles), # lpHandles
113 109 False, # bWaitAll
114 110 INFINITE) # dwMilliseconds
115 111
116 112 if WAIT_OBJECT_0 <= result < len(handles):
117 113 handle = handles[result - WAIT_OBJECT_0]
118 114
119 115 if handle == self.interrupt_handle:
120 raw_print('Interrupted by parent poller!')
121 116 interrupt_main()
122 117
123 118 elif handle == self.parent_handle:
124 raw_print('Killed by parent poller!')
125 119 os._exit(1)
General Comments 0
You need to be logged in to leave comments. Login now