[pypy-svn] r78813 - in pypy/branch/fast-forward: lib-python pypy/module/signal pypy/module/signal/test pypy/translator/c/src
arigo at codespeak.net
arigo at codespeak.net
Sun Nov 7 15:15:59 CET 2010
Author: arigo
Date: Sun Nov 7 15:15:57 2010
New Revision: 78813
Modified:
pypy/branch/fast-forward/lib-python/TODO
pypy/branch/fast-forward/pypy/module/signal/__init__.py
pypy/branch/fast-forward/pypy/module/signal/interp_signal.py
pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py
pypy/branch/fast-forward/pypy/translator/c/src/signals.h
Log:
signal.set_wakeup_fd().
Modified: pypy/branch/fast-forward/lib-python/TODO
==============================================================================
--- pypy/branch/fast-forward/lib-python/TODO (original)
+++ pypy/branch/fast-forward/lib-python/TODO Sun Nov 7 15:15:57 2010
@@ -44,7 +44,7 @@
- missing builtin: memoryview
-- signal.set_wakeup_fd()
+- signal.set_wakeup_fd() DONE
- add 'unicode' in ObjSpace.MethodTable + probably a default implementation that
falls back to space.str().
Modified: pypy/branch/fast-forward/pypy/module/signal/__init__.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/signal/__init__.py (original)
+++ pypy/branch/fast-forward/pypy/module/signal/__init__.py Sun Nov 7 15:15:57 2010
@@ -6,6 +6,7 @@
interpleveldefs = {
'signal': 'interp_signal.signal',
'getsignal': 'interp_signal.getsignal',
+ 'set_wakeup_fd': 'interp_signal.set_wakeup_fd',
'NSIG': 'space.wrap(interp_signal.NSIG)',
'SIG_DFL': 'space.wrap(interp_signal.SIG_DFL)',
'SIG_IGN': 'space.wrap(interp_signal.SIG_IGN)',
Modified: pypy/branch/fast-forward/pypy/module/signal/interp_signal.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/signal/interp_signal.py (original)
+++ pypy/branch/fast-forward/pypy/module/signal/interp_signal.py Sun Nov 7 15:15:57 2010
@@ -7,6 +7,7 @@
import py
from pypy.tool import autopath
from pypy.rlib import jit
+from pypy.rlib.rarithmetic import intmask
def setup():
for key, value in cpy_signal.__dict__.items():
@@ -25,6 +26,7 @@
include_dirs = [str(py.path.local(autopath.pypydir).join('translator', 'c'))],
export_symbols = ['pypysig_poll', 'pypysig_default',
'pypysig_ignore', 'pypysig_setflag',
+ 'pypysig_set_wakeup_fd',
'pypysig_getaddr_occurred'],
)
@@ -34,6 +36,7 @@
pypysig_ignore = external('pypysig_ignore', [rffi.INT], lltype.Void)
pypysig_default = external('pypysig_default', [rffi.INT], lltype.Void)
pypysig_setflag = external('pypysig_setflag', [rffi.INT], lltype.Void)
+pypysig_set_wakeup_fd = external('pypysig_set_wakeup_fd', [rffi.INT], rffi.INT)
pypysig_poll = external('pypysig_poll', [], rffi.INT, threadsafe=False)
# don't bother releasing the GIL around a call to pypysig_poll: it's
# pointless and a performance issue
@@ -213,3 +216,21 @@
action.handlers_w[signum] = w_handler
return old_handler
signal.unwrap_spec = [ObjSpace, int, W_Root]
+
+def set_wakeup_fd(space, fd):
+ """Sets the fd to be written to (with '\0') when a signal
+ comes in. Returns the old fd. A library can use this to
+ wakeup select or poll. The previous fd is returned.
+
+ The fd must be non-blocking.
+ """
+ if space.config.objspace.usemodules.thread:
+ main_ec = space.threadlocals.getmainthreadvalue()
+ ec = space.getexecutioncontext()
+ if ec is not main_ec:
+ raise OperationError(
+ space.w_ValueError,
+ space.wrap("set_wakeup_fd only works in main thread"))
+ old_fd = pypysig_set_wakeup_fd(fd)
+ return space.wrap(intmask(old_fd))
+set_wakeup_fd.unwrap_spec = [ObjSpace, int]
Modified: pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py (original)
+++ pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py Sun Nov 7 15:15:57 2010
@@ -136,6 +136,40 @@
finally:
signal(SIGALRM, SIG_DFL)
+ def test_set_wakeup_fd(self):
+ import signal, posix, fcntl
+ def myhandler(signum, frame):
+ pass
+ signal.signal(signal.SIGUSR1, myhandler)
+ #
+ def cannot_read():
+ try:
+ posix.read(fd_read, 1)
+ except OSError:
+ pass
+ else:
+ raise AssertionError, "os.read(fd_read, 1) succeeded?"
+ #
+ fd_read, fd_write = posix.pipe()
+ flags = fcntl.fcntl(fd_write, fcntl.F_GETFL, 0)
+ flags = flags | posix.O_NONBLOCK
+ fcntl.fcntl(fd_write, fcntl.F_SETFL, flags)
+ flags = fcntl.fcntl(fd_read, fcntl.F_GETFL, 0)
+ flags = flags | posix.O_NONBLOCK
+ fcntl.fcntl(fd_read, fcntl.F_SETFL, flags)
+ #
+ old_wakeup = signal.set_wakeup_fd(fd_write)
+ try:
+ cannot_read()
+ posix.kill(posix.getpid(), signal.SIGUSR1)
+ res = posix.read(fd_read, 1)
+ assert res == '\x00'
+ cannot_read()
+ finally:
+ old_wakeup = signal.set_wakeup_fd(old_wakeup)
+ #
+ signal.signal(signal.SIGUSR1, signal.SIG_DFL)
+
class AppTestSignalSocket:
@@ -168,4 +202,3 @@
alarm(0)
finally:
signal(SIGALRM, SIG_DFL)
-
Modified: pypy/branch/fast-forward/pypy/translator/c/src/signals.h
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/src/signals.h (original)
+++ pypy/branch/fast-forward/pypy/translator/c/src/signals.h Sun Nov 7 15:15:57 2010
@@ -43,6 +43,7 @@
void pypysig_default(int signum); /* signal will do default action (SIG_DFL) */
void pypysig_setflag(int signum); /* signal will set a flag which can be
queried with pypysig_poll() */
+int pypysig_set_wakeup_fd(int fd);
/* utility to poll for signals that arrived */
int pypysig_poll(void); /* => signum or -1 */
@@ -76,6 +77,7 @@
struct pypysig_long_struct pypysig_occurred;
static volatile long *pypysig_occurred_v = (volatile long *)&pypysig_occurred.value;
static volatile int pypysig_flags[NSIG];
+static int wakeup_fd = -1;
void pypysig_ignore(int signum)
{
@@ -112,6 +114,9 @@
/* the point of "*pypysig_occurred_v" instead of just "pypysig_occurred"
is the volatile declaration */
*pypysig_occurred_v |= PENDING_SIGNAL_BIT;
+
+ if (wakeup_fd != -1)
+ write(wakeup_fd, "\0", 1);
}
void pypysig_setflag(int signum)
@@ -151,6 +156,13 @@
return -1; /* no pending signal */
}
+int pypysig_set_wakeup_fd(int fd)
+{
+ int old_fd = wakeup_fd;
+ wakeup_fd = fd;
+ return old_fd;
+}
+
#endif
#endif
More information about the Pypy-commit
mailing list