mirror of
https://github.com/python/cpython.git
synced 2025-11-02 19:12:55 +00:00
Issue #16876: Revert be8e6b81284e, which wasn't thread-safe: wait until a
solution is found for poll().
This commit is contained in:
parent
e6f3d53138
commit
a6ebb2d7fb
2 changed files with 13 additions and 35 deletions
|
|
@ -233,9 +233,6 @@ Library
|
||||||
failing if the connection used a row factory (such as sqlite3.Row) that
|
failing if the connection used a row factory (such as sqlite3.Row) that
|
||||||
produced unsortable objects. (Regression was introduced by fix for 9750).
|
produced unsortable objects. (Regression was introduced by fix for 9750).
|
||||||
|
|
||||||
- Issue #16876: Optimize epoll.poll() by keeping a per-instance epoll events
|
|
||||||
buffer instead of allocating a new one at each poll().
|
|
||||||
|
|
||||||
- Issue #16491: IDLE now prints chained exception tracebacks.
|
- Issue #16491: IDLE now prints chained exception tracebacks.
|
||||||
|
|
||||||
- fcntl: add F_DUPFD_CLOEXEC constant, available on Linux 2.6.24+.
|
- fcntl: add F_DUPFD_CLOEXEC constant, available on Linux 2.6.24+.
|
||||||
|
|
|
||||||
|
|
@ -1056,14 +1056,9 @@ static int select_have_broken_poll(void)
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* default maximum number of events returned by epoll_wait() */
|
|
||||||
#define EPOLL_DEFAULT_MAXEVENTS (FD_SETSIZE)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
SOCKET epfd; /* epoll control file descriptor */
|
SOCKET epfd; /* epoll control file descriptor */
|
||||||
int maxevents; /* maximum number of epoll events */
|
|
||||||
struct epoll_event *evs; /* epoll events buffer */
|
|
||||||
} pyEpoll_Object;
|
} pyEpoll_Object;
|
||||||
|
|
||||||
static PyTypeObject pyEpoll_Type;
|
static PyTypeObject pyEpoll_Type;
|
||||||
|
|
@ -1119,15 +1114,6 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->maxevents = EPOLL_DEFAULT_MAXEVENTS;
|
|
||||||
self->evs = PyMem_New(struct epoll_event, self->maxevents);
|
|
||||||
if (!self->evs) {
|
|
||||||
Py_DECREF(self);
|
|
||||||
PyErr_NoMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1154,10 +1140,6 @@ static void
|
||||||
pyepoll_dealloc(pyEpoll_Object *self)
|
pyepoll_dealloc(pyEpoll_Object *self)
|
||||||
{
|
{
|
||||||
(void)pyepoll_internal_close(self);
|
(void)pyepoll_internal_close(self);
|
||||||
if (self->evs) {
|
|
||||||
PyMem_Free(self->evs);
|
|
||||||
self->evs = NULL;
|
|
||||||
}
|
|
||||||
Py_TYPE(self)->tp_free(self);
|
Py_TYPE(self)->tp_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1338,6 +1320,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
|
||||||
int maxevents = -1;
|
int maxevents = -1;
|
||||||
int nfds, i;
|
int nfds, i;
|
||||||
PyObject *elist = NULL, *etuple = NULL;
|
PyObject *elist = NULL, *etuple = NULL;
|
||||||
|
struct epoll_event *evs = NULL;
|
||||||
static char *kwlist[] = {"timeout", "maxevents", NULL};
|
static char *kwlist[] = {"timeout", "maxevents", NULL};
|
||||||
|
|
||||||
if (self->epfd < 0)
|
if (self->epfd < 0)
|
||||||
|
|
@ -1361,27 +1344,24 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxevents == -1) {
|
if (maxevents == -1) {
|
||||||
maxevents = EPOLL_DEFAULT_MAXEVENTS;
|
maxevents = FD_SETSIZE-1;
|
||||||
} else if (maxevents < 1) {
|
}
|
||||||
|
else if (maxevents < 1) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"maxevents must be greater than 0, got %d",
|
"maxevents must be greater than 0, got %d",
|
||||||
maxevents);
|
maxevents);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (maxevents > self->maxevents) {
|
|
||||||
struct epoll_event *orig_evs = self->evs;
|
|
||||||
|
|
||||||
PyMem_RESIZE(self->evs, struct epoll_event, maxevents);
|
evs = PyMem_New(struct epoll_event, maxevents);
|
||||||
if (!self->evs) {
|
if (evs == NULL) {
|
||||||
self->evs = orig_evs;
|
Py_DECREF(self);
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
self->maxevents = maxevents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
nfds = epoll_wait(self->epfd, self->evs, self->maxevents, timeout);
|
nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (nfds < 0) {
|
if (nfds < 0) {
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
|
@ -1394,7 +1374,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nfds; i++) {
|
for (i = 0; i < nfds; i++) {
|
||||||
etuple = Py_BuildValue("iI", self->evs[i].data.fd, self->evs[i].events);
|
etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
|
||||||
if (etuple == NULL) {
|
if (etuple == NULL) {
|
||||||
Py_CLEAR(elist);
|
Py_CLEAR(elist);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1403,6 +1383,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
PyMem_Free(evs);
|
||||||
return elist;
|
return elist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue