Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a6ebb2d

Browse files
committed
Issue #16876: Revert be8e6b81284e, which wasn't thread-safe: wait until a
solution is found for poll().
1 parent e6f3d53 commit a6ebb2d

2 files changed

Lines changed: 13 additions & 35 deletions

File tree

Misc/NEWS

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,6 @@ Library
233233
failing if the connection used a row factory (such as sqlite3.Row) that
234234
produced unsortable objects. (Regression was introduced by fix for 9750).
235235

236-
- Issue #16876: Optimize epoll.poll() by keeping a per-instance epoll events
237-
buffer instead of allocating a new one at each poll().
238-
239236
- Issue #16491: IDLE now prints chained exception tracebacks.
240237

241238
- fcntl: add F_DUPFD_CLOEXEC constant, available on Linux 2.6.24+.

Modules/selectmodule.c

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,14 +1056,9 @@ static int select_have_broken_poll(void)
10561056
#include <sys/epoll.h>
10571057
#endif
10581058

1059-
/* default maximum number of events returned by epoll_wait() */
1060-
#define EPOLL_DEFAULT_MAXEVENTS (FD_SETSIZE)
1061-
10621059
typedef struct {
10631060
PyObject_HEAD
1064-
SOCKET epfd; /* epoll control file descriptor */
1065-
int maxevents; /* maximum number of epoll events */
1066-
struct epoll_event *evs; /* epoll events buffer */
1061+
SOCKET epfd; /* epoll control file descriptor */
10671062
} pyEpoll_Object;
10681063

10691064
static PyTypeObject pyEpoll_Type;
@@ -1119,15 +1114,6 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
11191114
PyErr_SetFromErrno(PyExc_OSError);
11201115
return NULL;
11211116
}
1122-
1123-
self->maxevents = EPOLL_DEFAULT_MAXEVENTS;
1124-
self->evs = PyMem_New(struct epoll_event, self->maxevents);
1125-
if (!self->evs) {
1126-
Py_DECREF(self);
1127-
PyErr_NoMemory();
1128-
return NULL;
1129-
}
1130-
11311117
return (PyObject *)self;
11321118
}
11331119

@@ -1154,10 +1140,6 @@ static void
11541140
pyepoll_dealloc(pyEpoll_Object *self)
11551141
{
11561142
(void)pyepoll_internal_close(self);
1157-
if (self->evs) {
1158-
PyMem_Free(self->evs);
1159-
self->evs = NULL;
1160-
}
11611143
Py_TYPE(self)->tp_free(self);
11621144
}
11631145

@@ -1338,6 +1320,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
13381320
int maxevents = -1;
13391321
int nfds, i;
13401322
PyObject *elist = NULL, *etuple = NULL;
1323+
struct epoll_event *evs = NULL;
13411324
static char *kwlist[] = {"timeout", "maxevents", NULL};
13421325

13431326
if (self->epfd < 0)
@@ -1361,27 +1344,24 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
13611344
}
13621345

13631346
if (maxevents == -1) {
1364-
maxevents = EPOLL_DEFAULT_MAXEVENTS;
1365-
} else if (maxevents < 1) {
1347+
maxevents = FD_SETSIZE-1;
1348+
}
1349+
else if (maxevents < 1) {
13661350
PyErr_Format(PyExc_ValueError,
13671351
"maxevents must be greater than 0, got %d",
13681352
maxevents);
13691353
return NULL;
13701354
}
1371-
if (maxevents > self->maxevents) {
1372-
struct epoll_event *orig_evs = self->evs;
13731355

1374-
PyMem_RESIZE(self->evs, struct epoll_event, maxevents);
1375-
if (!self->evs) {
1376-
self->evs = orig_evs;
1377-
PyErr_NoMemory();
1378-
return NULL;
1379-
}
1380-
self->maxevents = maxevents;
1356+
evs = PyMem_New(struct epoll_event, maxevents);
1357+
if (evs == NULL) {
1358+
Py_DECREF(self);
1359+
PyErr_NoMemory();
1360+
return NULL;
13811361
}
13821362

13831363
Py_BEGIN_ALLOW_THREADS
1384-
nfds = epoll_wait(self->epfd, self->evs, self->maxevents, timeout);
1364+
nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
13851365
Py_END_ALLOW_THREADS
13861366
if (nfds < 0) {
13871367
PyErr_SetFromErrno(PyExc_OSError);
@@ -1394,7 +1374,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
13941374
}
13951375

13961376
for (i = 0; i < nfds; i++) {
1397-
etuple = Py_BuildValue("iI", self->evs[i].data.fd, self->evs[i].events);
1377+
etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
13981378
if (etuple == NULL) {
13991379
Py_CLEAR(elist);
14001380
goto error;
@@ -1403,6 +1383,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
14031383
}
14041384

14051385
error:
1386+
PyMem_Free(evs);
14061387
return elist;
14071388
}
14081389

0 commit comments

Comments
 (0)