diff -r 89665cc05592 Doc/library/signal.rst --- a/Doc/library/signal.rst Tue Jul 22 21:29:52 2014 +0100 +++ b/Doc/library/signal.rst Wed Jul 23 02:45:06 2014 +0200 @@ -303,13 +303,15 @@ The :mod:`signal` module defines the fol .. function:: set_wakeup_fd(fd) - Set the wakeup file descriptor to *fd*. When a signal is received, the - signal number is written as a single byte into the fd. This can be used by - a library to wakeup a poll or select call, allowing the signal to be fully - processed. + Set the file descriptor *fd* to non-blocking mode and set the wakeup file + descriptor to *fd*. - 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. + When a signal is received, the signal number is written as a single byte + into the *fd*. This can be used by a library to wakeup a poll or select + call, allowing the signal to be fully processed. + + It is up to the library to remove any bytes before calling poll or select + again. Use for example ``struct.unpack('%uB' % len(data), data)`` to decode the signal numbers list. diff -r 89665cc05592 Include/fileutils.h --- a/Include/fileutils.h Tue Jul 22 21:29:52 2014 +0100 +++ b/Include/fileutils.h Wed Jul 23 02:45:06 2014 +0200 @@ -70,6 +70,8 @@ PyAPI_FUNC(int) _Py_set_inheritable(int int *atomic_flag_works); PyAPI_FUNC(int) _Py_dup(int fd); + +PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); #endif #ifdef __cplusplus diff -r 89665cc05592 Lib/test/test_signal.py --- a/Lib/test/test_signal.py Tue Jul 22 21:29:52 2014 +0100 +++ b/Lib/test/test_signal.py Wed Jul 23 02:45:06 2014 +0200 @@ -276,7 +276,6 @@ class WakeupSignalTests(unittest.TestCas # use a subprocess to have only one thread code = """if 1: import _testcapi - import fcntl import os import signal import struct @@ -299,10 +298,6 @@ class WakeupSignalTests(unittest.TestCas signal.signal(signal.SIGALRM, handler) read, write = os.pipe() - for fd in (read, write): - flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) signal.set_wakeup_fd(write) test() @@ -322,7 +317,6 @@ class WakeupSignalTests(unittest.TestCas code = """if 1: import _testcapi import errno - import fcntl import os import signal import sys @@ -333,8 +327,6 @@ class WakeupSignalTests(unittest.TestCas signal.signal(signal.SIGALRM, handler) r, w = os.pipe() - flags = fcntl.fcntl(r, fcntl.F_GETFL, 0) - fcntl.fcntl(r, fcntl.F_SETFL, flags | os.O_NONBLOCK) # Set wakeup_fd a read-only file descriptor to trigger the error signal.set_wakeup_fd(r) diff -r 89665cc05592 Modules/signalmodule.c --- a/Modules/signalmodule.c Tue Jul 22 21:29:52 2014 +0100 +++ b/Modules/signalmodule.c Wed Jul 23 02:45:06 2014 +0200 @@ -428,6 +428,10 @@ signal_set_wakeup_fd(PyObject *self, PyO { struct stat buf; int fd, old_fd; +#ifdef MS_WINDOWS + u_long block; +#endif + if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) return NULL; #ifdef WITH_THREAD @@ -446,6 +450,15 @@ signal_set_wakeup_fd(PyObject *self, PyO if (fstat(fd, &buf) != 0) return PyErr_SetFromErrno(PyExc_OSError); + +#ifdef MS_WINDOWS + block = 1; + if (!ioctlsocket(s->sock_fd, FIONBIO, &block)) + return PyErr_SetFromWindowsErr(0); +#else + if (_Py_set_blocking(fd, 0) < 0) + return NULL; +#endif } old_fd = wakeup_fd; diff -r 89665cc05592 Modules/socketmodule.c --- a/Modules/socketmodule.c Tue Jul 22 21:29:52 2014 +0100 +++ b/Modules/socketmodule.c Wed Jul 23 02:45:06 2014 +0200 @@ -548,6 +548,9 @@ set_gaierror(int error) static int internal_setblocking(PySocketSockObject *s, int block) { +#ifdef MS_WINDOWS + u_long arg; +#endif #if !defined(MS_WINDOWS) \ && !((defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO))) int delay_flag, new_delay_flag; @@ -574,8 +577,8 @@ internal_setblocking(PySocketSockObject fcntl(s->sock_fd, F_SETFL, new_delay_flag); #endif #else /* MS_WINDOWS */ - block = !block; - ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block); + arg = !block; + ioctlsocket(s->sock_fd, FIONBIO, &arg); #endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS diff -r 89665cc05592 Python/fileutils.c --- a/Python/fileutils.c Tue Jul 22 21:29:52 2014 +0100 +++ b/Python/fileutils.c Wed Jul 23 02:45:06 2014 +0200 @@ -1045,3 +1045,36 @@ int return fd; } +#ifndef MS_WINDOWS +int +_Py_set_blocking(int fd, int blocking) +{ +#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) + int arg = !blocking; + if (ioctl(fd, FIONBIO, &arg) < 0) + goto error; +#else + int flags, res; + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + goto error; + + if (blocking) + flags = flags & (~O_NONBLOCK); + else + flags = flags | O_NONBLOCK; + + res = fcntl(fd, F_SETFL, flags); + if (res < 0) + goto error; + +#endif + return 0; + +error: + PyErr_SetFromErrno(PyExc_OSError); + return -1; +} +#endif +