[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