def run(self):
        child_fd = signalfd.signalfd(0, [signal.SIGCHLD], signalfd.SFD_NONBLOCK|signalfd.SFD_CLOEXEC)
        with os.fdopen(child_fd, 'rb') as child_signals:
            signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGCHLD])
            with closing(cloexec(socket.socket(socket.AF_UNIX, socket.SOCK_STREAM))) as requests_sock:
                if os.path.exists(self.socket_name):
                    os.unlink(self.socket_name)
                requests_sock.bind(self.socket_name)
                requests_sock.listen(self.socket_backlog)
                try:
                    while 1:
                        qlen = len(self.queues)
                        logger.debug("Queues => %s workspaces", qlen)
                        for i, wq in enumerate(self.queues.values()):
                            if i + 1 == qlen:
                                logger.debug(" \_ %s", wq)
                            else:
                                logger.debug(" |_ %s", wq)

                        current_fds = [child_fd, requests_sock]
                        current_fds.extend(self.clients.keys())
                        read_ready, _, errors = select.select(current_fds, [], current_fds, 1)
                        for fd in read_ready:
                            if requests_sock == fd:
                                self.handle_accept(requests_sock)
                            elif fd in self.clients:
                                self.handle_request(fd)
                            elif fd == child_fd:
                                self.handle_signal(child_signals)
                        for fd in errors:
                            logger.error("Fd %r has error !", fd)
                finally:
                    for fd, (fh, _) in self.clients.items():
                        close(fh, fd)
def test_read_fd_no_data():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1], signalfd.SFD_CLOEXEC | signalfd.SFD_NONBLOCK)
    try:
        err = pytest.raises((OSError, IOError), signalfd.read_siginfo, fd)
        assert err.value.errno == errno.EAGAIN
    finally:
        os.close(fd)
Exemple #3
0
def test_read_fd_no_data():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1],
                           signalfd.SFD_CLOEXEC | signalfd.SFD_NONBLOCK)
    try:
        err = pytest.raises((OSError, IOError), signalfd.read_siginfo, fd)
        assert err.value.errno == errno.EAGAIN
    finally:
        os.close(fd)
def test_read_fh_no_data():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1], signalfd.SFD_CLOEXEC | signalfd.SFD_NONBLOCK)
    fh = os.fdopen(fd, 'rb')
    try:
        err = pytest.raises((OSError, IOError), signalfd.read_siginfo, fh)
        assert err.value.errno == errno.EAGAIN
    finally:
        fh.close()
 def signalfd(self, *a, **kw):
     try:
         return signalfd.signalfd(*a, **kw)
     except OSError:
         type, value, traceback = sys.exc_info()
         if value.errno == errno.ENOSYS:
             raise unittest.Skip(
                 "signalfd() not implemented on this platform")
Exemple #6
0
def test_read_fh_no_data():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1],
                           signalfd.SFD_CLOEXEC | signalfd.SFD_NONBLOCK)
    fh = os.fdopen(fd, 'rb')
    try:
        err = pytest.raises((OSError, IOError), signalfd.read_siginfo, fh)
        assert err.value.errno == errno.EAGAIN
    finally:
        fh.close()
Exemple #7
0
def test_block_and_read():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1], signalfd.SFD_CLOEXEC)
    try:
        signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGUSR1])
        os.kill(os.getpid(), signal.SIGUSR1)
        si = signalfd.read_siginfo(fd)
        assert si.ssi_signo == signal.SIGUSR1
    finally:
        os.close(fd)
def test_block_and_read():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1], signalfd.SFD_CLOEXEC)
    try:
        signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGUSR1])
        os.kill(os.getpid(), signal.SIGUSR1)
        si = signalfd.read_siginfo(fd)
        assert si.ssi_signo == signal.SIGUSR1
    finally:
        os.close(fd)
    def run(self):
        child_fd = signalfd.signalfd(
            -1, [signal.SIGCHLD], signalfd.SFD_NONBLOCK | signalfd.SFD_CLOEXEC)
        with os.fdopen(child_fd, "rb") as child_signals:
            signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGCHLD])
            with closing(
                    cloexec(socket.socket(
                        socket.AF_UNIX, socket.SOCK_STREAM))) as requests_sock:
                logger.info("Binding to %r", self.socket_path)
                if os.path.exists(self.socket_path):
                    os.unlink(self.socket_path)
                pending_socket_path = "%s-pending" % self.socket_path
                requests_sock.bind(pending_socket_path)
                requests_sock.listen(self.socket_backlog)
                os.rename(pending_socket_path, self.socket_path)
                try:
                    while 1:
                        qlen = len(self.queues)
                        logger.debug("Queues => %s workspaces", qlen)
                        for i, wq in enumerate(self.queues.values()):
                            if i + 1 == qlen:
                                logger.debug(" \_ %s", wq)
                            else:
                                logger.debug(" |_ %s", wq)

                        current_fds = [child_fd, requests_sock]
                        current_fds.extend(self.clients.keys())
                        read_ready, _, errors = select.select(
                            current_fds, [], current_fds, 1)
                        for fd in read_ready:
                            if requests_sock == fd:
                                self.handle_accept(requests_sock)
                            elif fd in self.clients:
                                self.handle_request(fd)
                            elif fd == child_fd:
                                self.handle_signal(child_signals)
                        for fd in errors:
                            logger.error("Fd %r has error !", fd)
                finally:
                    for fd, (fh, _) in self.clients.items():
                        close(fh, fd)
def run_server(args):
	"""
	It is important that we create the signal FD and block the signals before doing anything
	else. Otherwise, we may get interrupted partway during initialization, and the resources we
	have allocated thus far will not be released.
	"""
	sig_fd = signalfd.signalfd(-1, shutdown_signals, SFD_NONBLOCK | SFD_CLOEXEC)
	signalfd.sigprocmask(SIG_BLOCK, shutdown_signals)

	sock, epoll = None, None
	conn_dict = {}

	try:
		sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		sock.setblocking(False)
		sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		sock.bind(('0.0.0.0', SERVER_PORT))

		epoll = select.epoll(sizehint=2, flags=EPOLL_CLOEXEC)
		epoll.register(sig_fd, EPOLLIN)
		epoll.register(sock, EPOLLIN)

		sock.listen(SERVER_BACKLOG_SIZE)
		print("Listening on {}:{}.".format(socket.gethostname(), SERVER_PORT),
			file=sys.stderr, flush=True)
		listen(sock, sig_fd, conn_dict, epoll)
	except SystemExit:
		print("Terminated.", file=sys.stderr, flush=True)
		raise
	finally:
		if epoll:
			epoll.close()

		os.close(sig_fd)
		if sock:
			close_socket(sock)
		for conn, _ in conn_dict.values():
			close_socket(conn)
Exemple #11
0
 def start(self, loglevel, logfile):
     """Start to work !"""
     logging.basicConfig(
         level=loglevel,
         stream=logfile,
         format=
         "%(levelname)s|%(asctime)s|%(process)d|%(filename)s|%(funcName)s|%(lineno)d| %(message)s"
     )
     global _LOGGER
     _LOGGER = logging.getLogger(__name__)
     self.init_sockets()
     _LOGGER.info("Worker %d started", self.worker_id)
     fd = signalfd.signalfd(-1, [signal.SIGTERM], signalfd.SFD_CLOEXEC)
     signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGTERM])
     with os.fdopen(fd) as fo:
         poller = zmq.Poller()
         poller.register(self.rep_sock, zmq.POLLIN)
         poller.register(fo, zmq.POLLIN)
         while True:
             try:
                 items = dict(poller.poll(1000))
                 if self.rep_sock in items:
                     cmd = self.rep_sock.recv()
                     _LOGGER.debug("cmd received from client: '%s'", cmd)
                     self.process_cmd(cmd)
                     _LOGGER.debug("cmd '%s' processed", cmd)
                 if fo.fileno() in items:
                     _LOGGER.debug("Signal received on worker %d",
                                   self.worker_id)
                     break
             except KeyboardInterrupt:
                 _LOGGER.debug("Keyboard interrrupt received on worker %d",
                               self.worker_id)
                 break
     _LOGGER.debug("Stopping worker %d", self.worker_id)
     self.rep_sock.close()
Exemple #12
0
     for i in range(TIMEOUT * 100):
         time.sleep(0.1)
 elif test_name == 'test_oneshot_on_usr2':
     manhole.install(oneshot_on='USR2')
     for i in range(TIMEOUT  * 100):
         time.sleep(0.1)
 elif test_name.startswith('test_signalfd_weirdness'):
     if 'negative' in test_name:
         manhole.install(sigmask=None)
     else:
         manhole.install(sigmask=[signal.SIGCHLD])
     time.sleep(0.3)  # give the manhole a bit enough time to start
     print('Starting ...')
     import signalfd
     signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGCHLD])
     fd = signalfd.signalfd(0, [signal.SIGCHLD], signalfd.SFD_NONBLOCK|signalfd.SFD_CLOEXEC)
     for i in range(200):
         print('Forking %s:' % i)
         pid = os.fork()
         print(' - [%s/%s] forked' % (i, pid))
         if pid:
             while 1:
                 print(' - [%s/%s] selecting on: %s' % (i, pid, [fd]))
                 read_ready, _, errors = select.select([fd], [], [fd], 1)
                 if read_ready:
                     try:
                         print(' - [%s/%s] reading from signalfd ...' % (i, pid))
                         print(' - [%s] read from signalfd: %r ' % (i, os.read(fd, 128)))
                         break
                     except OSError as exc:
                         print(' - [%s/%s] reading from signalfd failed with errno %s' % (i, pid, exc.errno))
Exemple #13
0
 def __init__(self, mask = [signal.SIGCHLD, signal.SIGTSTP]):
     self.mask = mask
     self.signal_handlers = {}
     IOHandler.__init__(self, signalfd.signalfd(-1, mask, signalfd.SFD_CLOEXEC | signalfd.SFD_NONBLOCK), usage="SignalManager")
     signalfd.sigprocmask(signalfd.SIG_BLOCK, mask)
Exemple #14
0
import os
import sys
import signal
import select
from signalfd import signalfd, sigset

# Create a signal set containing all signals.
mask = sigset()
mask.fill()

with signalfd(mask) as fd:
    poll = select.poll()
    poll.register(fd,  select.POLLIN)
    poll.register(sys.stdin, select.POLLIN)

    # Print signals as they are received until user presses <RETURN>.

    print '=' * 70
    print 'Send signals to this process (%d) or press RETURN to exit.' % os.getpid()
    print '=' * 70

    while True:
        events = dict(poll.poll())

        if fd.fileno() in events:
            info = fd.info()
            print 'received signal %d' % info.ssi_signo

        if sys.stdin.fileno() in events:
            print 'all done'
            break
Exemple #15
0
 def __init__(self, mask = [signal.SIGCHLD]):
     self.mask = mask
     self.signal_handlers = {}
     IOHandler.__init__(self, signalfd.signalfd(-1, mask, signalfd.SFD_CLOEXEC | signalfd.SFD_NONBLOCK), usage="SignalManager")
     signalfd.sigprocmask(signalfd.SIG_BLOCK, mask)
def test_read_closed():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1], signalfd.SFD_CLOEXEC)
    os.close(fd)
    pytest.raises(OSError, signalfd.read_siginfo, fd)
Exemple #17
0
def test_read_closed():
    fd = signalfd.signalfd(-1, [signal.SIGUSR1], signalfd.SFD_CLOEXEC)
    os.close(fd)
    pytest.raises(OSError, signalfd.read_siginfo, fd)
Exemple #18
0
     for i in range(TIMEOUT * 100):
         time.sleep(0.1)
 elif test_name == 'test_oneshot_on_usr2':
     manhole.install(oneshot_on='USR2')
     for i in range(TIMEOUT * 100):
         time.sleep(0.1)
 elif test_name.startswith('test_signalfd_weirdness'):
     if 'negative' in test_name:
         manhole.install(sigmask=None)
     else:
         manhole.install(sigmask=[signal.SIGCHLD])
     print('Starting ...')
     import signalfd
     signalfd.sigprocmask(signalfd.SIG_BLOCK, [signal.SIGCHLD])
     fd = signalfd.signalfd(
         0, [signal.SIGCHLD],
         signalfd.SFD_NONBLOCK | signalfd.SFD_CLOEXEC)
     for i in range(200):
         print('Forking %s:' % i)
         pid = os.fork()
         print(' - [%s/%s] forked' % (i, pid))
         if pid:
             while 1:
                 print(' - [%s/%s] selecting on: %s' % (i, pid, [fd]))
                 read_ready, _, errors = select.select([fd], [], [fd],
                                                       1)
                 if read_ready:
                     try:
                         print(' - [%s/%s] reading from signalfd ...' %
                               (i, pid))
                         print(' - [%s] read from signalfd: %r ' %