Skip to content

Commit de1d4fc

Browse files
authored
Merge e03f8f0 into 3d00568
2 parents 3d00568 + e03f8f0 commit de1d4fc

4 files changed

Lines changed: 36 additions & 15 deletions

File tree

Lib/test/eintrdata/eintr_tester.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,6 @@ def test_select(self):
442442
self.stop_alarm()
443443
self.assertGreaterEqual(dt, self.sleep_time)
444444

445-
@unittest.skipIf(sys.platform == "darwin",
446-
"poll may fail on macOS; see issue #28087")
447445
@unittest.skipUnless(hasattr(select, 'poll'), 'need select.poll')
448446
def test_poll(self):
449447
poller = select.poll()

Lib/test/test_asyncore.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,6 @@ def test_handle_expt(self):
661661
if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX:
662662
self.skipTest("Not applicable to AF_UNIX sockets.")
663663

664-
if sys.platform == "darwin" and self.use_poll:
665-
self.skipTest("poll may fail on macOS; see issue #28087")
666-
667664
class TestClient(BaseClient):
668665
def handle_expt(self):
669666
self.socket.recv(1024, socket.MSG_OOB)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ Extension Modules
317317
Library
318318
-------
319319

320+
- bpo-28087: On macOS, check for broken poll() at runtime on macOS Sierra
321+
16.0.x-16.5.x. Disable select.poll() (remove select.poll) if poll() is
322+
broken.
323+
320324
- bpo-30103: binascii.b2a_uu() and uu.encode() now support using ``'`'``
321325
as zero instead of space.
322326

Modules/selectmodule.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
#include <structmember.h>
1313

1414
#ifdef HAVE_SYS_DEVPOLL_H
15-
#include <sys/resource.h>
16-
#include <sys/devpoll.h>
17-
#include <sys/types.h>
18-
#include <sys/stat.h>
19-
#include <fcntl.h>
15+
# include <sys/resource.h>
16+
# include <sys/devpoll.h>
17+
# include <sys/types.h>
18+
# include <sys/stat.h>
19+
# include <fcntl.h>
20+
#endif
21+
#ifdef __APPLE__
22+
# include <sys/utsname.h> /* select_have_broken_poll() */
2023
#endif
2124

2225
#ifdef __APPLE__
@@ -1182,10 +1185,27 @@ select_devpoll(PyObject *self, PyObject *unused)
11821185
*/
11831186
static int select_have_broken_poll(void)
11841187
{
1185-
int poll_test;
11861188
int filedes[2];
1187-
1189+
struct utsname u;
11881190
struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
1191+
int res;
1192+
const char *release;
1193+
1194+
res = uname(&u);
1195+
if (res < 0) {
1196+
/* unlikely uname() failure: disable poll() */
1197+
return 1;
1198+
}
1199+
1200+
release = u.release;
1201+
/* bpo-28087: macOS 16.0.x-16.5.x has a broken poll().
1202+
* poll() with no file descriptors registered returns immediately,
1203+
* regardless of the timeout. */
1204+
if (strncmp(release, "16.", 3) == 0
1205+
&& '0' <= release[3] && release[3] <= '5'
1206+
&& release[4] == '.') {
1207+
return 1;
1208+
}
11891209

11901210
/* Create a file descriptor to make invalid */
11911211
if (pipe(filedes) < 0) {
@@ -1194,10 +1214,12 @@ static int select_have_broken_poll(void)
11941214
poll_struct.fd = filedes[0];
11951215
close(filedes[0]);
11961216
close(filedes[1]);
1197-
poll_test = poll(&poll_struct, 1, 0);
1198-
if (poll_test < 0) {
1217+
1218+
res = poll(&poll_struct, 1, 0);
1219+
if (res < 0) {
11991220
return 1;
1200-
} else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1221+
}
1222+
else if (res == 0 && poll_struct.revents != POLLNVAL) {
12011223
return 1;
12021224
}
12031225
return 0;

0 commit comments

Comments
 (0)