]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Backout 42ced0d023cd: oops, i didn't want to push this changeset :-/
authorVictor Stinner <victor.stinner@gmail.com>
Thu, 24 Jul 2014 20:51:05 +0000 (22:51 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Thu, 24 Jul 2014 20:51:05 +0000 (22:51 +0200)
Doc/c-api/exceptions.rst
Doc/library/signal.rst
Lib/test/test_signal.py
Modules/signalmodule.c
PCbuild/pythoncore.vcxproj

index 46033ca7389d4bceab9a039e71859fda4f50079e..33b44390d24ca20d301e8e06f50b9b9e5767cb02 100644 (file)
@@ -443,20 +443,13 @@ in various ways.  There is a separate error indicator for each thread.
 
 .. 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)
 
index cda228bdc954f9b2bd72fc091f3f11a38d1d83dd..a97ce66ef522314c07f3b24a64bb22269f284225 100644 (file)
@@ -308,8 +308,6 @@ The :mod:`signal` module defines the following functions:
    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 @@ The :mod:`signal` module defines the following functions:
    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)
 
index 28bb4d6e23f25b9dd0b571a97f940bdbb66dcede..56ab6316b61d2e82418b986771b94663b593a857 100644 (file)
@@ -6,7 +6,6 @@ import gc
 import pickle
 import select
 import signal
-import socket
 import struct
 import subprocess
 import traceback
@@ -252,43 +251,21 @@ class WindowsSignalTests(unittest.TestCase):
 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):
-        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)
+        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)
+
+        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 @@ class WakeupSignalTests(unittest.TestCase):
         """,  signal.SIGUSR1, signal.SIGUSR2, ordered=False)
 
 
-@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 @@ def test_main():
     try:
         support.run_unittest(GenericTests, PosixTests, InterProcessSignalTests,
                              WakeupFDTests, WakeupSignalTests,
-                             WakeupSocketSignalTests,
                              SiginterruptTest, ItimerTest, WindowsSignalTests,
                              PendingSignalsTests)
     finally:
index a315f23a038e7ebdf098b34421a677b72846ead5..c4f0121644412224c47118a024491c4b9a444ecf 100644 (file)
@@ -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 @@ static volatile struct {
     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 @@ checksignals_witharg(void * unused)
     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 @@ report_wakeup_error(void *data)
     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);
-        }
-    }
-#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);
+        while ((rc = write(wakeup_fd, &byte, 1)) == -1 && errno == EINTR);
+        if (rc == -1)
+            Py_AddPendingCall(report_wakeup_error, (void *) (Py_intptr_t) errno);
     }
+    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 @@ signal_siginterrupt(PyObject *self, PyObject *args)
 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 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args)
     }
 #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);
-            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);
+        if (!_PyVerify_fd(fd)) {
+            PyErr_SetString(PyExc_ValueError, "invalid fd");
             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 @@ The fd must be non-blocking.");
 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;
 }
 
index 1ad16fb82222bc8f75521fe87d62225f70d59c02..6021cd74cbfb7811e98d78dd4e82115428c62ff8 100644 (file)
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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 @@ IF %ERRORLEVEL% NEQ 0 (
       <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>