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 | 69 | self.interrupt_handle = interrupt_handle |
|
70 | 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 | 72 | def run(self): |
|
107 | 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 | 175 | cwd = cast_bytes_py2(cwd, sys.getfilesystemencoding() or 'ascii') |
|
176 | 176 | kwargs['cwd'] = cwd |
|
177 | 177 | |
|
178 | from jupyter_client.parentpoller import ParentPollerWindows | |
|
178 | from .win_interrupt import create_interrupt_event | |
|
179 | 179 | # Create a Win32 event for interrupting the kernel |
|
180 | 180 | # and store it in an environment variable. |
|
181 |
interrupt_event = |
|
|
181 | interrupt_event = create_interrupt_event() | |
|
182 | 182 | env["JPY_INTERRUPT_EVENT"] = str(interrupt_event) |
|
183 | 183 | # deprecated old env name: |
|
184 | 184 | env["IPY_INTERRUPT_EVENT"] = env["JPY_INTERRUPT_EVENT"] |
@@ -381,8 +381,8 b' class KernelManager(ConnectionFileMixin):' | |||
|
381 | 381 | """ |
|
382 | 382 | if self.has_kernel: |
|
383 | 383 | if sys.platform == 'win32': |
|
384 |
from . |
|
|
385 |
|
|
|
384 | from .win_interrupt import send_interrupt | |
|
385 | send_interrupt(self.kernel.win32_interrupt_event) | |
|
386 | 386 | else: |
|
387 | 387 | self.kernel.send_signal(signal.SIGINT) |
|
388 | 388 | else: |
General Comments 0
You need to be logged in to leave comments.
Login now