Ausgabe der neuen DB Einträge
This commit is contained in:
parent
bad48e1627
commit
cfbbb9ee3d
2399 changed files with 843193 additions and 43 deletions
|
|
@ -0,0 +1,68 @@
|
|||
# -*- test-case-name: twisted.internet.test.test_sigchld -*-
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
This module is used to integrate child process termination into a
|
||||
reactor event loop. This is a challenging feature to provide because
|
||||
most platforms indicate process termination via SIGCHLD and do not
|
||||
provide a way to wait for that signal and arbitrary I/O events at the
|
||||
same time. The naive implementation involves installing a Python
|
||||
SIGCHLD handler; unfortunately this leads to other syscalls being
|
||||
interrupted (whenever SIGCHLD is received) and failing with EINTR
|
||||
(which almost no one is prepared to handle). This interruption can be
|
||||
disabled via siginterrupt(2) (or one of the equivalent mechanisms);
|
||||
however, if the SIGCHLD is delivered by the platform to a non-main
|
||||
thread (not a common occurrence, but difficult to prove impossible),
|
||||
the main thread (waiting on select() or another event notification
|
||||
API) may not wake up leading to an arbitrary delay before the child
|
||||
termination is noticed.
|
||||
|
||||
The basic solution to all these issues involves enabling SA_RESTART
|
||||
(ie, disabling system call interruption) and registering a C signal
|
||||
handler which writes a byte to a pipe. The other end of the pipe is
|
||||
registered with the event loop, allowing it to wake up shortly after
|
||||
SIGCHLD is received. See L{twisted.internet.posixbase._SIGCHLDWaker}
|
||||
for the implementation of the event loop side of this solution. The
|
||||
use of a pipe this way is known as the U{self-pipe
|
||||
trick<http://cr.yp.to/docs/selfpipe.html>}.
|
||||
|
||||
From Python version 2.6, C{signal.siginterrupt} and C{signal.set_wakeup_fd}
|
||||
provide the necessary C signal handler which writes to the pipe to be
|
||||
registered with C{SA_RESTART}.
|
||||
"""
|
||||
|
||||
from __future__ import division, absolute_import
|
||||
|
||||
import signal
|
||||
|
||||
|
||||
def installHandler(fd):
|
||||
"""
|
||||
Install a signal handler which will write a byte to C{fd} when
|
||||
I{SIGCHLD} is received.
|
||||
|
||||
This is implemented by installing a SIGCHLD handler that does nothing,
|
||||
setting the I{SIGCHLD} handler as not allowed to interrupt system calls,
|
||||
and using L{signal.set_wakeup_fd} to do the actual writing.
|
||||
|
||||
@param fd: The file descriptor to which to write when I{SIGCHLD} is
|
||||
received.
|
||||
@type fd: C{int}
|
||||
"""
|
||||
if fd == -1:
|
||||
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
|
||||
else:
|
||||
def noopSignalHandler(*args):
|
||||
pass
|
||||
signal.signal(signal.SIGCHLD, noopSignalHandler)
|
||||
signal.siginterrupt(signal.SIGCHLD, False)
|
||||
return signal.set_wakeup_fd(fd)
|
||||
|
||||
|
||||
|
||||
def isDefaultHandler():
|
||||
"""
|
||||
Determine whether the I{SIGCHLD} handler is the default or not.
|
||||
"""
|
||||
return signal.getsignal(signal.SIGCHLD) == signal.SIG_DFL
|
||||
Loading…
Add table
Add a link
Reference in a new issue