win_interrupt.py
39 lines
| 1.4 KiB
| text/x-python
|
PythonLexer
/ jupyter_client / win_interrupt.py
Thomas Kluyver
|
r21021 | """Use a Windows event to interrupt a child process like SIGINT. | ||
The child needs to explicitly listen for this - see | ||||
ipython_kernel.parentpoller.ParentPollerWindows for a Python implementation. | ||||
""" | ||||
import ctypes | ||||
def create_interrupt_event(): | ||||
"""Create an interrupt event handle. | ||||
The parent process should call this to create the | ||||
interrupt event that is passed to the child process. It should store | ||||
this handle and use it with ``send_interrupt`` to interrupt the child | ||||
process. | ||||
""" | ||||
# Create a security attributes struct that permits inheritance of the | ||||
# handle by new processes. | ||||
# FIXME: We can clean up this mess by requiring pywin32 for IPython. | ||||
class SECURITY_ATTRIBUTES(ctypes.Structure): | ||||
_fields_ = [ ("nLength", ctypes.c_int), | ||||
("lpSecurityDescriptor", ctypes.c_void_p), | ||||
("bInheritHandle", ctypes.c_int) ] | ||||
sa = SECURITY_ATTRIBUTES() | ||||
sa_p = ctypes.pointer(sa) | ||||
sa.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES) | ||||
sa.lpSecurityDescriptor = 0 | ||||
sa.bInheritHandle = 1 | ||||
return ctypes.windll.kernel32.CreateEventA( | ||||
sa_p, # lpEventAttributes | ||||
False, # bManualReset | ||||
False, # bInitialState | ||||
'') # lpName | ||||
def send_interrupt(interrupt_handle): | ||||
""" Sends an interrupt event using the specified handle. | ||||
""" | ||||
ctypes.windll.kernel32.SetEvent(interrupt_handle) | ||||