##// END OF EJS Templates
Merge pull request #4546 from minrk/not-in-dir-warning...
Merge pull request #4546 from minrk/not-in-dir-warning fix warning condition on notebook startup

File last commit:

r13587:210d5e2f
r13643:29626775 merge
Show More
parentpoller.py
142 lines | 4.9 KiB | text/x-python | PythonLexer
epatters
Implemented kernel interrupts for Windows.
r3027 # Standard library imports.
MinRK
avoid ctypes import in parentpoller when unnecessary
r6127 try:
import ctypes
except:
ctypes = None
epatters
Implemented kernel interrupts for Windows.
r3027 import os
Min Ragan-Kelley
handle different pointer size on x64 Windows...
r4253 import platform
epatters
Implemented kernel interrupts for Windows.
r3027 import time
Thomas Kluyver
Update imports for Python 3...
r13354 try:
from _thread import interrupt_main # Py 3
except ImportError:
from thread import interrupt_main # Py 2
epatters
Implemented kernel interrupts for Windows.
r3027 from threading import Thread
Min RK
warn and stop polling if WaitForMultipleObjects fails
r4258 from IPython.utils.warn import warn
epatters
Implemented kernel interrupts for Windows.
r3027
class ParentPollerUnix(Thread):
Bernardo B. Marques
remove all trailling spaces
r4872 """ A Unix-specific daemon thread that terminates the program immediately
epatters
Implemented kernel interrupts for Windows.
r3027 when the parent process no longer exists.
"""
def __init__(self):
super(ParentPollerUnix, self).__init__()
self.daemon = True
Bernardo B. Marques
remove all trailling spaces
r4872
epatters
Implemented kernel interrupts for Windows.
r3027 def run(self):
# We cannot use os.waitpid because it works only for child processes.
from errno import EINTR
while True:
try:
if os.getppid() == 1:
os._exit(1)
time.sleep(1.0)
Matthias BUSSONNIER
conform to pep 3110...
r7787 except OSError as e:
epatters
Implemented kernel interrupts for Windows.
r3027 if e.errno == EINTR:
continue
raise
class ParentPollerWindows(Thread):
""" A Windows-specific daemon thread that listens for a special event that
signals an interrupt and, optionally, terminates the program immediately
when the parent process no longer exists.
"""
Bernardo B. Marques
remove all trailling spaces
r4872
epatters
Implemented kernel interrupts for Windows.
r3027 def __init__(self, interrupt_handle=None, parent_handle=None):
""" Create the poller. At least one of the optional parameters must be
provided.
Thomas Kluyver
Clean up numpydoc section headers
r13587 Parameters
----------
epatters
Implemented kernel interrupts for Windows.
r3027 interrupt_handle : HANDLE (int), optional
If provided, the program will generate a Ctrl+C event when this
handle is signaled.
parent_handle : HANDLE (int), optional
Bernardo B. Marques
remove all trailling spaces
r4872 If provided, the program will terminate immediately when this
epatters
Implemented kernel interrupts for Windows.
r3027 handle is signaled.
"""
assert(interrupt_handle or parent_handle)
super(ParentPollerWindows, self).__init__()
MinRK
avoid ctypes import in parentpoller when unnecessary
r6127 if ctypes is None:
raise ImportError("ParentPollerWindows requires ctypes")
epatters
Implemented kernel interrupts for Windows.
r3027 self.daemon = True
self.interrupt_handle = interrupt_handle
self.parent_handle = parent_handle
@staticmethod
def create_interrupt_event():
""" Create an interrupt event handle.
The parent process should use this static method for creating 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):
Bernardo B. Marques
remove all trailling spaces
r4872 _fields_ = [ ("nLength", ctypes.c_int),
("lpSecurityDescriptor", ctypes.c_void_p),
epatters
Implemented kernel interrupts for Windows.
r3027 ("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
@staticmethod
def send_interrupt(interrupt_handle):
""" Sends an interrupt event using the specified handle.
"""
ctypes.windll.kernel32.SetEvent(interrupt_handle)
def run(self):
""" Run the poll loop. This method never returns.
"""
MinRK
use new _winapi instead of removed _subprocess...
r8557 try:
from _winapi import WAIT_OBJECT_0, INFINITE
except ImportError:
from _subprocess import WAIT_OBJECT_0, INFINITE
epatters
Implemented kernel interrupts for Windows.
r3027
# Build the list of handle to listen on.
handles = []
if self.interrupt_handle:
handles.append(self.interrupt_handle)
if self.parent_handle:
handles.append(self.parent_handle)
Min Ragan-Kelley
handle different pointer size on x64 Windows...
r4253 arch = platform.architecture()[0]
c_int = ctypes.c_int64 if arch.startswith('64') else ctypes.c_int
epatters
Implemented kernel interrupts for Windows.
r3027
# Listen forever.
while True:
result = ctypes.windll.kernel32.WaitForMultipleObjects(
len(handles), # nCount
Min Ragan-Kelley
handle different pointer size on x64 Windows...
r4253 (c_int * len(handles))(*handles), # lpHandles
epatters
Implemented kernel interrupts for Windows.
r3027 False, # bWaitAll
INFINITE) # dwMilliseconds
if WAIT_OBJECT_0 <= result < len(handles):
handle = handles[result - WAIT_OBJECT_0]
if handle == self.interrupt_handle:
interrupt_main()
elif handle == self.parent_handle:
os._exit(1)
Min Ragan-Kelley
handle different pointer size on x64 Windows...
r4253 elif result < 0:
Min RK
warn and stop polling if WaitForMultipleObjects fails
r4258 # wait failed, just give up and stop polling.
warn("""Parent poll failed. If the frontend dies,
the kernel may be left running. Please let us know
about your system (bitness, Python, etc.) at
ipython-dev@scipy.org""")
return