[Python-checkins] cpython: Backout 42ced0d023cd: oops, i didn't want to push this changeset :-/

victor.stinner python-checkins at python.org
Thu Jul 24 22:51:23 CEST 2014


http://hg.python.org/cpython/rev/96ea15ee8525
changeset:   91838:96ea15ee8525
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Thu Jul 24 22:51:05 2014 +0200
summary:
  Backout 42ced0d023cd: oops, i didn't want to push this changeset :-/

files:
  Doc/c-api/exceptions.rst   |   13 +-
  Doc/library/signal.rst     |    5 -
  Lib/test/test_signal.py    |  130 +-------------------
  Modules/signalmodule.c     |  155 +++---------------------
  PCbuild/pythoncore.vcxproj |   16 +-
  5 files changed, 41 insertions(+), 278 deletions(-)


diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -443,20 +443,13 @@
 
 .. c:function:: int PySignal_SetWakeupFd(int fd)
 
-   This utility function specifies a file descriptor to which the signal number
-   is written as a single byte whenever a signal is received. *fd* must be
-   non-blocking. It returns the previous such file descriptor.
-
-   On Windows, the function only supports socket handles.
-
-   The value ``-1`` disables the feature; this is the initial state.
+   This utility function specifies a file descriptor to which a ``'\0'`` byte will
+   be written whenever a signal is received.  It returns the previous such file
+   descriptor.  The value ``-1`` disables the feature; this is the initial state.
    This is equivalent to :func:`signal.set_wakeup_fd` in Python, but without any
    error checking.  *fd* should be a valid file descriptor.  The function should
    only be called from the main thread.
 
-   .. versionchanged:: 3.5
-      On Windows, the function now only supports socket handles.
-
 
 .. c:function:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)
 
diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst
--- a/Doc/library/signal.rst
+++ b/Doc/library/signal.rst
@@ -308,8 +308,6 @@
    a library to wakeup a poll or select call, allowing the signal to be fully
    processed.
 
-   On Windows, the function only supports socket handles.
-
    The old wakeup fd is returned.  *fd* must be non-blocking.  It is up to the
    library to remove any bytes before calling poll or select again.
 
@@ -320,9 +318,6 @@
    attempting to call it from other threads will cause a :exc:`ValueError`
    exception to be raised.
 
-   .. versionchanged:: 3.5
-      On Windows, the function now only supports socket handles.
-
 
 .. function:: siginterrupt(signalnum, flag)
 
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -6,7 +6,6 @@
 import pickle
 import select
 import signal
-import socket
 import struct
 import subprocess
 import traceback
@@ -252,43 +251,21 @@
 class WakeupFDTests(unittest.TestCase):
 
     def test_invalid_fd(self):
-        if sys.platform == "win32":
-            sock = socket.socket()
-            fd = sock.fileno()
-            sock.close()
-        else:
-            fd = support.make_bad_fd()
+        fd = support.make_bad_fd()
         self.assertRaises((ValueError, OSError),
                           signal.set_wakeup_fd, fd)
 
-    @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows')
-    def test_only_socket(self):
-        # set_wakeup_fd() expects a socket on Windows
-        with open(support.TESTFN, 'wb') as fp:
-            self.addCleanup(support.unlink, support.TESTFN)
-            self.assertRaises(ValueError,
-                              signal.set_wakeup_fd, fp.fileno())
+    def test_set_wakeup_fd_result(self):
+        r1, w1 = os.pipe()
+        self.addCleanup(os.close, r1)
+        self.addCleanup(os.close, w1)
+        r2, w2 = os.pipe()
+        self.addCleanup(os.close, r2)
+        self.addCleanup(os.close, w2)
 
-    def test_set_wakeup_fd_result(self):
-        if sys.platform == 'win32':
-            sock1 = socket.socket()
-            self.addCleanup(sock1.close)
-            fd1 = sock1.fileno()
-
-            sock2 = socket.socket()
-            self.addCleanup(sock2.close)
-            fd2 = sock2.fileno()
-        else:
-            r1, fd1 = os.pipe()
-            self.addCleanup(os.close, r1)
-            self.addCleanup(os.close, fd1)
-            r2, fd2 = os.pipe()
-            self.addCleanup(os.close, r2)
-            self.addCleanup(os.close, fd2)
-
-        signal.set_wakeup_fd(fd1)
-        self.assertIs(signal.set_wakeup_fd(fd2), fd1)
-        self.assertIs(signal.set_wakeup_fd(-1), fd2)
+        signal.set_wakeup_fd(w1)
+        self.assertIs(signal.set_wakeup_fd(w2), w1)
+        self.assertIs(signal.set_wakeup_fd(-1), w2)
         self.assertIs(signal.set_wakeup_fd(-1), -1)
 
 
@@ -464,90 +441,6 @@
         """,  signal.SIGUSR1, signal.SIGUSR2, ordered=False)
 
 
- at unittest.skipUnless(hasattr(socket, 'socketpair'), 'need socket.socketpair')
-class WakeupSocketSignalTests(unittest.TestCase):
-
-    @unittest.skipIf(_testcapi is None, 'need _testcapi')
-    def test_socket(self):
-        # use a subprocess to have only one thread
-        code = """if 1:
-        import signal
-        import socket
-        import struct
-        import _testcapi
-
-        signum = signal.SIGINT
-        signals = (signum,)
-
-        def handler(signum, frame):
-            pass
-
-        signal.signal(signum, handler)
-
-        read, write = socket.socketpair()
-        read.setblocking(False)
-        write.setblocking(False)
-        signal.set_wakeup_fd(write.fileno())
-
-        _testcapi.raise_signal(signum)
-
-        data = read.recv(1)
-        if not data:
-            raise Exception("no signum written")
-        raised = struct.unpack('B', data)
-        if raised != signals:
-            raise Exception("%r != %r" % (raised, signals))
-
-        read.close()
-        write.close()
-        """
-
-        assert_python_ok('-c', code)
-
-    @unittest.skipIf(_testcapi is None, 'need _testcapi')
-    def test_send_error(self):
-        # Use a subprocess to have only one thread.
-        if os.name == 'nt':
-            action = 'send'
-        else:
-            action = 'write'
-        code = """if 1:
-        import errno
-        import signal
-        import socket
-        import sys
-        import time
-        import _testcapi
-        from test.support import captured_stderr
-
-        signum = signal.SIGINT
-
-        def handler(signum, frame):
-            pass
-
-        signal.signal(signum, handler)
-
-        read, write = socket.socketpair()
-        read.setblocking(False)
-        write.setblocking(False)
-
-        signal.set_wakeup_fd(write.fileno())
-
-        # Close sockets: send() will fail
-        read.close()
-        write.close()
-
-        with captured_stderr() as err:
-            _testcapi.raise_signal(signum)
-
-        err = err.getvalue()
-        if ('Exception ignored when trying to {action} to the signal wakeup fd'
-            not in err):
-            raise AssertionError(err)
-        """.format(action=action)
-        assert_python_ok('-c', code)
-
-
 @unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
 class SiginterruptTest(unittest.TestCase):
 
@@ -1097,7 +990,6 @@
     try:
         support.run_unittest(GenericTests, PosixTests, InterProcessSignalTests,
                              WakeupFDTests, WakeupSignalTests,
-                             WakeupSocketSignalTests,
                              SiginterruptTest, ItimerTest, WindowsSignalTests,
                              PendingSignalsTests)
     finally:
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -4,9 +4,6 @@
 /* XXX Signals should be recorded per thread, now we have thread state. */
 
 #include "Python.h"
-#ifdef MS_WINDOWS
-#include "socketmodule.h"   /* needed for SOCKET_T */
-#endif
 #ifndef MS_WINDOWS
 #include "posixmodule.h"
 #endif
@@ -90,18 +87,7 @@
     PyObject *func;
 } Handlers[NSIG];
 
-#ifdef MS_WINDOWS
-#define INVALID_SOCKET ((SOCKET_T)-1)
-
-static volatile struct {
-    SOCKET_T fd;
-    int send_err_set;
-    int send_errno;
-    int send_win_error;
-} wakeup = {INVALID_SOCKET, 0, 0};
-#else
 static volatile sig_atomic_t wakeup_fd = -1;
-#endif
 
 /* Speed up sigcheck() when none tripped */
 static volatile sig_atomic_t is_tripped = 0;
@@ -185,33 +171,6 @@
     return PyErr_CheckSignals();
 }
 
-#ifdef MS_WINDOWS
-static int
-report_wakeup_error(void* Py_UNUSED(data))
-{
-    PyObject *res;
-
-    if (wakeup.send_win_error) {
-        /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
-           recognizes the error codes used by both GetLastError() and
-           WSAGetLastError */
-        res = PyErr_SetExcFromWindowsErr(PyExc_OSError, wakeup.send_win_error);
-    }
-    else {
-        errno = wakeup.send_errno;
-        res = PyErr_SetFromErrno(PyExc_OSError);
-    }
-
-    assert(res == NULL);
-    wakeup.send_err_set = 0;
-
-    PySys_WriteStderr("Exception ignored when trying to send to the "
-                      "signal wakeup fd:\n");
-    PyErr_WriteUnraisable(NULL);
-
-    return 0;
-}
-#else
 static int
 report_wakeup_error(void *data)
 {
@@ -224,51 +183,26 @@
     errno = save_errno;
     return 0;
 }
-#endif
 
 static void
 trip_signal(int sig_num)
 {
     unsigned char byte;
-    Py_ssize_t rc;
+    int rc = 0;
 
     Handlers[sig_num].tripped = 1;
-
-#ifdef MS_WINDOWS
-    if (wakeup.fd != INVALID_SOCKET) {
-        byte = (unsigned char)sig_num;
-        do {
-            rc = send(wakeup.fd, &byte, 1, 0);
-        } while (rc < 0 && errno == EINTR);
-
-        /* we only have a storage for one error in the wakeup structure */
-        if (rc < 0 && !wakeup.send_err_set) {
-            wakeup.send_err_set = 1;
-            wakeup.send_errno = errno;
-            wakeup.send_win_error = GetLastError();
-            Py_AddPendingCall(report_wakeup_error, NULL);
-        }
-    }
-#else
     if (wakeup_fd != -1) {
         byte = (unsigned char)sig_num;
-        do {
-            rc = write(wakeup_fd, &byte, 1);
-        } while (rc < 0 && errno == EINTR);
-
-        if (rc < 0) {
-            Py_AddPendingCall(report_wakeup_error,
-                              (void *)(Py_intptr_t)errno);
-        }
+        while ((rc = write(wakeup_fd, &byte, 1)) == -1 && errno == EINTR);
+        if (rc == -1)
+            Py_AddPendingCall(report_wakeup_error, (void *) (Py_intptr_t) errno);
     }
-#endif
-
-    if (!is_tripped) {
-        /* Set is_tripped after setting .tripped, as it gets
-           cleared in PyErr_CheckSignals() before .tripped. */
-        is_tripped = 1;
-        Py_AddPendingCall(checksignals_witharg, NULL);
-    }
+    if (is_tripped)
+        return;
+    /* Set is_tripped after setting .tripped, as it gets
+       cleared in PyErr_CheckSignals() before .tripped. */
+    is_tripped = 1;
+    Py_AddPendingCall(checksignals_witharg, NULL);
 }
 
 static void
@@ -492,28 +426,10 @@
 static PyObject *
 signal_set_wakeup_fd(PyObject *self, PyObject *args)
 {
-#ifdef MS_WINDOWS
-    PyObject *fdobj;
-    SOCKET_T fd, old_fd;
-    int res;
-    int res_size = sizeof res;
-    PyObject *mod;
-    struct stat st;
-
-    if (!PyArg_ParseTuple(args, "O:set_wakeup_fd", &fdobj))
-        return NULL;
-
-    fd = PyLong_AsSocket_t(fdobj);
-    if (fd == (SOCKET_T)(-1) && PyErr_Occurred())
-        return NULL;
-#else
+    struct stat buf;
     int fd, old_fd;
-    struct stat st;
-
     if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd))
         return NULL;
-#endif
-
 #ifdef WITH_THREAD
     if (PyThread_get_thread_ident() != main_thread) {
         PyErr_SetString(PyExc_ValueError,
@@ -522,54 +438,28 @@
     }
 #endif
 
-#ifdef MS_WINDOWS
-    if (fd != INVALID_SOCKET) {
-        /* Import the _socket module to call WSAStartup() */
-        mod = PyImport_ImportModuleNoBlock("_socket");
-        if (mod == NULL)
-            return NULL;
-        Py_DECREF(mod);
-
-        /* test the socket */
-        if (getsockopt(fd, SOL_SOCKET, SO_ERROR,
-                       (char *)&res, &res_size) != 0) {
-            int err = WSAGetLastError();
-            if (err == WSAENOTSOCK)
-                PyErr_SetString(PyExc_ValueError, "fd is not a socket");
-            else
-                PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
+    if (fd != -1) {
+        if (!_PyVerify_fd(fd)) {
+            PyErr_SetString(PyExc_ValueError, "invalid fd");
             return NULL;
         }
-    }
 
-    old_fd = wakeup.fd;
-    wakeup.fd = fd;
-
-    if (old_fd != INVALID_SOCKET)
-        return PyLong_FromSocket_t(old_fd);
-    else
-        return PyLong_FromLong(-1);
-#else
-    if (fd != -1) {
-        if (fstat(fd, &st) != 0) {
-            PyErr_SetFromErrno(PyExc_OSError);
-            return NULL;
-        }
+        if (fstat(fd, &buf) != 0)
+            return PyErr_SetFromErrno(PyExc_OSError);
     }
 
     old_fd = wakeup_fd;
     wakeup_fd = fd;
 
     return PyLong_FromLong(old_fd);
-#endif
 }
 
 PyDoc_STRVAR(set_wakeup_fd_doc,
 "set_wakeup_fd(fd) -> fd\n\
 \n\
-Sets the fd to be written to (with the signal number) when a signal\n\
+Sets the fd to be written to (with '\\0') when a signal\n\
 comes in.  A library can use this to wakeup select or poll.\n\
-The previous fd or -1 is returned.\n\
+The previous fd is returned.\n\
 \n\
 The fd must be non-blocking.");
 
@@ -577,17 +467,10 @@
 int
 PySignal_SetWakeupFd(int fd)
 {
-    int old_fd;
+    int old_fd = wakeup_fd;
     if (fd < 0)
         fd = -1;
-
-#ifdef MS_WINDOWS
-    old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
-    wakeup.fd = fd;
-#else
-    old_fd = wakeup_fd;
     wakeup_fd = fd;
-#endif
     return old_fd;
 }
 
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -176,7 +176,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(PyDllName).dll</OutputFile>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
@@ -212,7 +212,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
     </Link>
@@ -247,7 +247,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
     </Link>
@@ -285,7 +285,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
     </Link>
@@ -317,7 +317,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(PyDllName).dll</OutputFile>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
@@ -353,7 +353,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
       <TargetMachine>MachineX64</TargetMachine>
@@ -386,7 +386,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(PyDllName).dll</OutputFile>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
@@ -422,7 +422,7 @@
       <Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
     </PreLinkEvent>
     <Link>
-      <AdditionalDependencies>$(IntDir)getbuildinfo.o;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>libc;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
       <BaseAddress>0x1e000000</BaseAddress>
       <TargetMachine>MachineX64</TargetMachine>

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list