mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 06:16:10 -04:00
Backport epoll memory fix for bug 2839240
svn:r1430
This commit is contained in:
parent
81765181c6
commit
1bf18e5a06
@ -1,5 +1,7 @@
|
|||||||
Changes in 1.4.13-stable:
|
Changes in 1.4.13-stable:
|
||||||
o If the kernel tells us that there are a negative number of bytes to read from a socket, do not believe it. Fixes bug 2841177; found by Alexander Pronchenkov.
|
o If the kernel tells us that there are a negative number of bytes to read from a socket, do not believe it. Fixes bug 2841177; found by Alexander Pronchenkov.
|
||||||
|
o Do not allocate the maximum event queue and fd array for the epoll backend at startup. Instead, start out accepting 32 events at a time, and double the queue's size when it seems that the OS is generating events faster than we're requesting them. Saves up to 512K per epoll-based event_base. Resolves bug 2839240.
|
||||||
|
|
||||||
|
|
||||||
Changes in 1.4.12-stable:
|
Changes in 1.4.12-stable:
|
||||||
o Try to contain degree of failure when running on a win32 version so heavily firewalled that we can't fake a socketpair.
|
o Try to contain degree of failure when running on a win32 version so heavily firewalled that we can't fake a socketpair.
|
||||||
|
44
epoll.c
44
epoll.c
@ -94,8 +94,6 @@ const struct eventop epollops = {
|
|||||||
#define FD_CLOSEONEXEC(x)
|
#define FD_CLOSEONEXEC(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NEVENT 32000
|
|
||||||
|
|
||||||
/* On Linux kernels at least up to 2.6.24.4, epoll can't handle timeout
|
/* On Linux kernels at least up to 2.6.24.4, epoll can't handle timeout
|
||||||
* values bigger than (LONG_MAX - 999ULL)/HZ. HZ in the wild can be
|
* values bigger than (LONG_MAX - 999ULL)/HZ. HZ in the wild can be
|
||||||
* as big as 1000, and LONG_MAX can be as small as (1<<31)-1, so the
|
* as big as 1000, and LONG_MAX can be as small as (1<<31)-1, so the
|
||||||
@ -104,30 +102,22 @@ const struct eventop epollops = {
|
|||||||
*/
|
*/
|
||||||
#define MAX_EPOLL_TIMEOUT_MSEC (35*60*1000)
|
#define MAX_EPOLL_TIMEOUT_MSEC (35*60*1000)
|
||||||
|
|
||||||
|
#define INITIAL_NFILES 32
|
||||||
|
#define INITIAL_NEVENTS 32
|
||||||
|
#define MAX_NEVENTS 4096
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
epoll_init(struct event_base *base)
|
epoll_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
int epfd, nfiles = NEVENT;
|
int epfd;
|
||||||
struct rlimit rl;
|
|
||||||
struct epollop *epollop;
|
struct epollop *epollop;
|
||||||
|
|
||||||
/* Disable epollueue when this environment variable is set */
|
/* Disable epollueue when this environment variable is set */
|
||||||
if (getenv("EVENT_NOEPOLL"))
|
if (getenv("EVENT_NOEPOLL"))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
|
|
||||||
rl.rlim_cur != RLIM_INFINITY) {
|
|
||||||
/*
|
|
||||||
* Solaris is somewhat retarded - it's important to drop
|
|
||||||
* backwards compatibility when making changes. So, don't
|
|
||||||
* dare to put rl.rlim_cur here.
|
|
||||||
*/
|
|
||||||
nfiles = rl.rlim_cur - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initalize the kernel queue */
|
/* Initalize the kernel queue */
|
||||||
|
if ((epfd = epoll_create(32000)) == -1) {
|
||||||
if ((epfd = epoll_create(nfiles)) == -1) {
|
|
||||||
if (errno != ENOSYS)
|
if (errno != ENOSYS)
|
||||||
event_warn("epoll_create");
|
event_warn("epoll_create");
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -141,20 +131,20 @@ epoll_init(struct event_base *base)
|
|||||||
epollop->epfd = epfd;
|
epollop->epfd = epfd;
|
||||||
|
|
||||||
/* Initalize fields */
|
/* Initalize fields */
|
||||||
epollop->events = malloc(nfiles * sizeof(struct epoll_event));
|
epollop->events = malloc(INITIAL_NEVENTS * sizeof(struct epoll_event));
|
||||||
if (epollop->events == NULL) {
|
if (epollop->events == NULL) {
|
||||||
free(epollop);
|
free(epollop);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
epollop->nevents = nfiles;
|
epollop->nevents = INITIAL_NEVENTS;
|
||||||
|
|
||||||
epollop->fds = calloc(nfiles, sizeof(struct evepoll));
|
epollop->fds = calloc(INITIAL_NFILES, sizeof(struct evepoll));
|
||||||
if (epollop->fds == NULL) {
|
if (epollop->fds == NULL) {
|
||||||
free(epollop->events);
|
free(epollop->events);
|
||||||
free(epollop);
|
free(epollop);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
epollop->nfds = nfiles;
|
epollop->nfds = INITIAL_NFILES;
|
||||||
|
|
||||||
evsignal_init(base);
|
evsignal_init(base);
|
||||||
|
|
||||||
@ -252,6 +242,20 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
event_active(evwrite, EV_WRITE, 1);
|
event_active(evwrite, EV_WRITE, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res == epollop->nevents && epollop->nevents < MAX_NEVENTS) {
|
||||||
|
/* We used all of the event space this time. We should
|
||||||
|
be ready for more events next time. */
|
||||||
|
int new_nevents = epollop->nevents * 2;
|
||||||
|
struct epoll_event *new_events;
|
||||||
|
|
||||||
|
new_events = realloc(epollop->events,
|
||||||
|
new_nevents * sizeof(struct epoll_event));
|
||||||
|
if (new_events) {
|
||||||
|
epollop->events = new_events;
|
||||||
|
epollop->nevents = new_nevents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user