[pypy-commit] pypy py3.3: Add signal.sigwait()
amauryfa
noreply at buildbot.pypy.org
Sun Jan 4 19:14:12 CET 2015
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.3
Changeset: r75230:385525065b2d
Date: 2015-01-04 14:29 +0100
http://bitbucket.org/pypy/pypy/changeset/385525065b2d/
Log: Add signal.sigwait()
diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py
--- a/pypy/module/signal/__init__.py
+++ b/pypy/module/signal/__init__.py
@@ -26,6 +26,7 @@
interpleveldefs[name] = 'space.wrap(interp_signal.%s)' % (name,)
if os.name == 'posix':
+ interpleveldefs['sigwait'] = 'interp_signal.sigwait'
interpleveldefs['pthread_kill'] = 'interp_signal.pthread_kill'
appleveldefs = {
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -5,14 +5,14 @@
import os
import errno
-from pypy.interpreter.error import OperationError, exception_from_errno
+from pypy.interpreter.error import OperationError, oefmt, exception_from_errno
from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag,
PeriodicAsyncAction)
from pypy.interpreter.gateway import unwrap_spec
from rpython.rlib import jit, rposix, rgc
from rpython.rlib.objectmodel import we_are_translated
-from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.rarithmetic import intmask, widen
from rpython.rlib.rsignal import *
from rpython.rtyper.lltypesystem import lltype, rffi
@@ -334,7 +334,38 @@
def pthread_kill(space, tid, signum):
"Send a signal to a thread."
ret = c_pthread_kill(tid, signum)
- if ret != 0:
+ if widen(ret) < 0:
raise exception_from_errno(space, space.w_OSError)
# the signal may have been send to the current thread
space.getexecutioncontext().checksignals()
+
+
+class SignalMask(object):
+ def __init__(self, space, w_signals):
+ self.space = space
+ self.w_signals = w_signals
+
+ def __enter__(self):
+ space = self.space
+ self.mask = lltype.malloc(c_sigset_t.TO, flavor='raw')
+ c_sigemptyset(self.mask)
+ for w_signum in space.unpackiterable(self.w_signals):
+ signum = space.int_w(w_signum)
+ check_signum_in_range(space, signum)
+ err = c_sigaddset(self.mask, signum)
+ if err:
+ raise oefmt(space.w_ValueError,
+ "signal number %d out of range", signum)
+ return self.mask
+
+ def __exit__(self, *args):
+ lltype.free(self.mask, flavor='raw')
+
+def sigwait(space, w_signals):
+ with SignalMask(space, w_signals) as sigset:
+ with lltype.scoped_alloc(rffi.INTP.TO, 1) as signum_ptr:
+ ret = c_sigwait(sigset, signum_ptr)
+ if ret != 0:
+ raise exception_from_errno(space, space.w_OSError)
+ signum = signum_ptr[0]
+ return space.wrap(signum)
diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -333,3 +333,12 @@
tid = _thread.get_ident()
raises(ZeroDivisionError, signal.pthread_kill, tid, signum)
+ def test_sigwait(self):
+ import signal
+ def handler(signum, frame):
+ 1/0
+ signal.signal(signal.SIGALRM, handler)
+ signal.alarm(1)
+ received = signal.sigwait([signal.SIGALRM])
+ assert received == signal.SIGALRM
+
diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py
--- a/rpython/rlib/rsignal.py
+++ b/rpython/rlib/rsignal.py
@@ -98,3 +98,9 @@
c_getitimer = external('getitimer', [rffi.INT, itimervalP], rffi.INT)
c_pthread_kill = external('pthread_kill', [lltype.Signed, rffi.INT], rffi.INT)
+
+if sys.platform != 'win32':
+ c_sigset_t = rffi.COpaquePtr('sigset_t', compilation_info=eci)
+ c_sigemptyset = external('sigemptyset', [c_sigset_t], rffi.INT)
+ c_sigaddset = external('sigaddset', [c_sigset_t, rffi.INT], rffi.INT)
+ c_sigwait = external('sigwait', [c_sigset_t, rffi.INTP], rffi.INT)
More information about the pypy-commit
mailing list