OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> | 2 * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 16 matching lines...) Expand all Loading... |
27 #ifdef HAVE_CONFIG_H | 27 #ifdef HAVE_CONFIG_H |
28 #include "config.h" | 28 #include "config.h" |
29 #endif | 29 #endif |
30 | 30 |
31 #include <stdint.h> | 31 #include <stdint.h> |
32 #include <sys/types.h> | 32 #include <sys/types.h> |
33 #include <sys/resource.h> | 33 #include <sys/resource.h> |
34 #ifdef HAVE_SYS_TIME_H | 34 #ifdef HAVE_SYS_TIME_H |
35 #include <sys/time.h> | 35 #include <sys/time.h> |
36 #else | 36 #else |
37 #include <sys/_time.h> | 37 #include <sys/_libevent_time.h> |
38 #endif | 38 #endif |
39 #include <sys/queue.h> | 39 #include <sys/queue.h> |
40 #include <sys/epoll.h> | 40 #include <sys/epoll.h> |
41 #include <signal.h> | 41 #include <signal.h> |
42 #include <stdio.h> | 42 #include <stdio.h> |
43 #include <stdlib.h> | 43 #include <stdlib.h> |
44 #include <string.h> | 44 #include <string.h> |
45 #include <unistd.h> | 45 #include <unistd.h> |
46 #include <errno.h> | 46 #include <errno.h> |
47 #ifdef HAVE_FCNTL_H | 47 #ifdef HAVE_FCNTL_H |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 87 |
88 #ifdef HAVE_SETFD | 88 #ifdef HAVE_SETFD |
89 #define FD_CLOSEONEXEC(x) do { \ | 89 #define FD_CLOSEONEXEC(x) do { \ |
90 if (fcntl(x, F_SETFD, 1) == -1) \ | 90 if (fcntl(x, F_SETFD, 1) == -1) \ |
91 event_warn("fcntl(%d, F_SETFD)", x); \ | 91 event_warn("fcntl(%d, F_SETFD)", x); \ |
92 } while (0) | 92 } while (0) |
93 #else | 93 #else |
94 #define FD_CLOSEONEXEC(x) | 94 #define FD_CLOSEONEXEC(x) |
95 #endif | 95 #endif |
96 | 96 |
97 #define NEVENT 32 | |
98 | |
99 /* On Linux kernels at least up to 2.6.24.4, epoll can't handle timeout | 97 /* On Linux kernels at least up to 2.6.24.4, epoll can't handle timeout |
100 * values bigger than (LONG_MAX - 999ULL)/HZ. HZ in the wild can be | 98 * values bigger than (LONG_MAX - 999ULL)/HZ. HZ in the wild can be |
101 * as big as 1000, and LONG_MAX can be as small as (1<<31)-1, so the | 99 * as big as 1000, and LONG_MAX can be as small as (1<<31)-1, so the |
102 * largest number of msec we can support here is 2147482. Let's | 100 * largest number of msec we can support here is 2147482. Let's |
103 * round that down by 47 seconds. | 101 * round that down by 47 seconds. |
104 */ | 102 */ |
105 #define MAX_EPOLL_TIMEOUT_MSEC (35*60*1000) | 103 #define MAX_EPOLL_TIMEOUT_MSEC (35*60*1000) |
106 | 104 |
| 105 #define INITIAL_NFILES 32 |
| 106 #define INITIAL_NEVENTS 32 |
| 107 #define MAX_NEVENTS 4096 |
| 108 |
107 static void * | 109 static void * |
108 epoll_init(struct event_base *base) | 110 epoll_init(struct event_base *base) |
109 { | 111 { |
110 » int epfd, nfiles = NEVENT; | 112 » int epfd; |
111 » struct rlimit rl; | |
112 struct epollop *epollop; | 113 struct epollop *epollop; |
113 | 114 |
114 /* Disable epollueue when this environment variable is set */ | 115 /* Disable epollueue when this environment variable is set */ |
115 » if (getenv("EVENT_NOEPOLL")) | 116 » if (evutil_getenv("EVENT_NOEPOLL")) |
116 return (NULL); | 117 return (NULL); |
117 | 118 |
118 /* Initalize the kernel queue */ | 119 /* Initalize the kernel queue */ |
119 | 120 » if ((epfd = epoll_create(32000)) == -1) { |
120 » if ((epfd = epoll_create(nfiles)) == -1) { | |
121 if (errno != ENOSYS) | 121 if (errno != ENOSYS) |
122 event_warn("epoll_create"); | 122 event_warn("epoll_create"); |
123 return (NULL); | 123 return (NULL); |
124 } | 124 } |
125 | 125 |
126 FD_CLOSEONEXEC(epfd); | 126 FD_CLOSEONEXEC(epfd); |
127 | 127 |
128 if (!(epollop = calloc(1, sizeof(struct epollop)))) | 128 if (!(epollop = calloc(1, sizeof(struct epollop)))) |
129 return (NULL); | 129 return (NULL); |
130 | 130 |
131 epollop->epfd = epfd; | 131 epollop->epfd = epfd; |
132 | 132 |
133 /* Initalize fields */ | 133 /* Initalize fields */ |
134 » epollop->events = malloc(nfiles * sizeof(struct epoll_event)); | 134 » epollop->events = malloc(INITIAL_NEVENTS * sizeof(struct epoll_event)); |
135 if (epollop->events == NULL) { | 135 if (epollop->events == NULL) { |
136 free(epollop); | 136 free(epollop); |
137 return (NULL); | 137 return (NULL); |
138 } | 138 } |
139 » epollop->nevents = nfiles; | 139 » epollop->nevents = INITIAL_NEVENTS; |
140 | 140 |
141 » epollop->fds = calloc(nfiles, sizeof(struct evepoll)); | 141 » epollop->fds = calloc(INITIAL_NFILES, sizeof(struct evepoll)); |
142 if (epollop->fds == NULL) { | 142 if (epollop->fds == NULL) { |
143 free(epollop->events); | 143 free(epollop->events); |
144 free(epollop); | 144 free(epollop); |
145 return (NULL); | 145 return (NULL); |
146 } | 146 } |
147 » epollop->nfds = nfiles; | 147 » epollop->nfds = INITIAL_NFILES; |
148 | 148 |
149 evsignal_init(base); | 149 evsignal_init(base); |
150 | 150 |
151 return (epollop); | 151 return (epollop); |
152 } | 152 } |
153 | 153 |
154 static int | 154 static int |
155 epoll_recalc(struct event_base *base, void *arg, int max) | 155 epoll_recalc(struct event_base *base, void *arg, int max) |
156 { | 156 { |
157 struct epollop *epollop = arg; | 157 struct epollop *epollop = arg; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 235 |
236 if (!(evread||evwrite)) | 236 if (!(evread||evwrite)) |
237 continue; | 237 continue; |
238 | 238 |
239 if (evread != NULL) | 239 if (evread != NULL) |
240 event_active(evread, EV_READ, 1); | 240 event_active(evread, EV_READ, 1); |
241 if (evwrite != NULL) | 241 if (evwrite != NULL) |
242 event_active(evwrite, EV_WRITE, 1); | 242 event_active(evwrite, EV_WRITE, 1); |
243 } | 243 } |
244 | 244 |
| 245 if (res == epollop->nevents && epollop->nevents < MAX_NEVENTS) { |
| 246 /* We used all of the event space this time. We should |
| 247 be ready for more events next time. */ |
| 248 int new_nevents = epollop->nevents * 2; |
| 249 struct epoll_event *new_events; |
| 250 |
| 251 new_events = realloc(epollop->events, |
| 252 new_nevents * sizeof(struct epoll_event)); |
| 253 if (new_events) { |
| 254 epollop->events = new_events; |
| 255 epollop->nevents = new_nevents; |
| 256 } |
| 257 } |
| 258 |
245 return (0); | 259 return (0); |
246 } | 260 } |
247 | 261 |
248 | 262 |
249 static int | 263 static int |
250 epoll_add(void *arg, struct event *ev) | 264 epoll_add(void *arg, struct event *ev) |
251 { | 265 { |
252 struct epollop *epollop = arg; | 266 struct epollop *epollop = arg; |
253 struct epoll_event epev = {0, {0}}; | 267 struct epoll_event epev = {0, {0}}; |
254 struct evepoll *evep; | 268 struct evepoll *evep; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 if (epollop->fds) | 368 if (epollop->fds) |
355 free(epollop->fds); | 369 free(epollop->fds); |
356 if (epollop->events) | 370 if (epollop->events) |
357 free(epollop->events); | 371 free(epollop->events); |
358 if (epollop->epfd >= 0) | 372 if (epollop->epfd >= 0) |
359 close(epollop->epfd); | 373 close(epollop->epfd); |
360 | 374 |
361 memset(epollop, 0, sizeof(struct epollop)); | 375 memset(epollop, 0, sizeof(struct epollop)); |
362 free(epollop); | 376 free(epollop); |
363 } | 377 } |
OLD | NEW |