##// END OF EJS Templates
Separate parent functionality from ParentPollerWindows...
Thomas Kluyver -
Show More
@@ -0,0 +1,39 b''
1 """Use a Windows event to interrupt a child process like SIGINT.
2
3 The child needs to explicitly listen for this - see
4 ipython_kernel.parentpoller.ParentPollerWindows for a Python implementation.
5 """
6
7 import ctypes
8
9 def create_interrupt_event():
10 """Create an interrupt event handle.
11
12 The parent process should call this to create the
13 interrupt event that is passed to the child process. It should store
14 this handle and use it with ``send_interrupt`` to interrupt the child
15 process.
16 """
17 # Create a security attributes struct that permits inheritance of the
18 # handle by new processes.
19 # FIXME: We can clean up this mess by requiring pywin32 for IPython.
20 class SECURITY_ATTRIBUTES(ctypes.Structure):
21 _fields_ = [ ("nLength", ctypes.c_int),
22 ("lpSecurityDescriptor", ctypes.c_void_p),
23 ("bInheritHandle", ctypes.c_int) ]
24 sa = SECURITY_ATTRIBUTES()
25 sa_p = ctypes.pointer(sa)
26 sa.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
27 sa.lpSecurityDescriptor = 0
28 sa.bInheritHandle = 1
29
30 return ctypes.windll.kernel32.CreateEventA(
31 sa_p, # lpEventAttributes
32 False, # bManualReset
33 False, # bInitialState
34 '') # lpName
35
36 def send_interrupt(interrupt_handle):
37 """ Sends an interrupt event using the specified handle.
38 """
39 ctypes.windll.kernel32.SetEvent(interrupt_handle)
@@ -69,40 +69,6 b' class ParentPollerWindows(Thread):'
69 self.interrupt_handle = interrupt_handle
69 self.interrupt_handle = interrupt_handle
70 self.parent_handle = parent_handle
70 self.parent_handle = parent_handle
71
71
72 @staticmethod
73 def create_interrupt_event():
74 """ Create an interrupt event handle.
75
76 The parent process should use this static method for creating the
77 interrupt event that is passed to the child process. It should store
78 this handle and use it with ``send_interrupt`` to interrupt the child
79 process.
80 """
81 # Create a security attributes struct that permits inheritance of the
82 # handle by new processes.
83 # FIXME: We can clean up this mess by requiring pywin32 for IPython.
84 class SECURITY_ATTRIBUTES(ctypes.Structure):
85 _fields_ = [ ("nLength", ctypes.c_int),
86 ("lpSecurityDescriptor", ctypes.c_void_p),
87 ("bInheritHandle", ctypes.c_int) ]
88 sa = SECURITY_ATTRIBUTES()
89 sa_p = ctypes.pointer(sa)
90 sa.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
91 sa.lpSecurityDescriptor = 0
92 sa.bInheritHandle = 1
93
94 return ctypes.windll.kernel32.CreateEventA(
95 sa_p, # lpEventAttributes
96 False, # bManualReset
97 False, # bInitialState
98 '') # lpName
99
100 @staticmethod
101 def send_interrupt(interrupt_handle):
102 """ Sends an interrupt event using the specified handle.
103 """
104 ctypes.windll.kernel32.SetEvent(interrupt_handle)
105
106 def run(self):
72 def run(self):
107 """ Run the poll loop. This method never returns.
73 """ Run the poll loop. This method never returns.
108 """
74 """
@@ -175,10 +175,10 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
175 cwd = cast_bytes_py2(cwd, sys.getfilesystemencoding() or 'ascii')
175 cwd = cast_bytes_py2(cwd, sys.getfilesystemencoding() or 'ascii')
176 kwargs['cwd'] = cwd
176 kwargs['cwd'] = cwd
177
177
178 from jupyter_client.parentpoller import ParentPollerWindows
178 from .win_interrupt import create_interrupt_event
179 # Create a Win32 event for interrupting the kernel
179 # Create a Win32 event for interrupting the kernel
180 # and store it in an environment variable.
180 # and store it in an environment variable.
181 interrupt_event = ParentPollerWindows.create_interrupt_event()
181 interrupt_event = create_interrupt_event()
182 env["JPY_INTERRUPT_EVENT"] = str(interrupt_event)
182 env["JPY_INTERRUPT_EVENT"] = str(interrupt_event)
183 # deprecated old env name:
183 # deprecated old env name:
184 env["IPY_INTERRUPT_EVENT"] = env["JPY_INTERRUPT_EVENT"]
184 env["IPY_INTERRUPT_EVENT"] = env["JPY_INTERRUPT_EVENT"]
@@ -381,8 +381,8 b' class KernelManager(ConnectionFileMixin):'
381 """
381 """
382 if self.has_kernel:
382 if self.has_kernel:
383 if sys.platform == 'win32':
383 if sys.platform == 'win32':
384 from .parentpoller import ParentPollerWindows as Poller
384 from .win_interrupt import send_interrupt
385 Poller.send_interrupt(self.kernel.win32_interrupt_event)
385 send_interrupt(self.kernel.win32_interrupt_event)
386 else:
386 else:
387 self.kernel.send_signal(signal.SIGINT)
387 self.kernel.send_signal(signal.SIGINT)
388 else:
388 else:
General Comments 0
You need to be logged in to leave comments. Login now