9
10
#include <ngx_event.h>
13
13
static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer);
14
14
static void ngx_select_done(ngx_cycle_t *cycle);
15
15
static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event,
19
19
static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
21
static void ngx_select_repair_fd_sets(ngx_cycle_t *cycle);
21
22
static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
26
27
static fd_set work_read_fd_set;
27
28
static fd_set work_write_fd_set;
30
static ngx_uint_t max_read;
31
static ngx_uint_t max_write;
33
30
static ngx_int_t max_fd;
36
31
static ngx_uint_t nevents;
38
33
static ngx_event_t **event_index;
151
if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
152
|| (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
140
if ((event == NGX_READ_EVENT && ev->write)
141
|| (event == NGX_WRITE_EVENT && !ev->write))
154
ngx_log_error(NGX_LOG_ERR, ev->log, 0,
155
"maximum number of descriptors "
156
"supported by select() is %d", FD_SETSIZE);
143
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
144
"invalid select %s event fd:%d ev:%i",
145
ev->write ? "write" : "read", c->fd, event);
157
146
return NGX_ERROR;
160
149
if (event == NGX_READ_EVENT) {
161
150
FD_SET(c->fd, &master_read_fd_set);
164
} else if (event == NGX_WRITE_EVENT) {
165
FD_SET(c->fd, &master_write_fd_set);
171
if (event == NGX_READ_EVENT) {
172
FD_SET(c->fd, &master_read_fd_set);
174
152
} else if (event == NGX_WRITE_EVENT) {
175
153
FD_SET(c->fd, &master_write_fd_set);
207
184
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
208
185
"select del event fd:%d ev:%i", c->fd, event);
212
if (event == NGX_READ_EVENT) {
213
FD_CLR(c->fd, &master_read_fd_set);
216
} else if (event == NGX_WRITE_EVENT) {
217
FD_CLR(c->fd, &master_write_fd_set);
223
187
if (event == NGX_READ_EVENT) {
224
188
FD_CLR(c->fd, &master_read_fd_set);
236
198
if (ev->index < --nevents) {
237
event_index[ev->index] = event_index[nevents];
238
event_index[ev->index]->index = ev->index;
199
e = event_index[nevents];
200
event_index[ev->index] = e;
201
e->index = ev->index;
241
204
ev->index = NGX_INVALID_INDEX;
248
211
ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
249
212
ngx_uint_t flags)
254
ngx_event_t *ev, **queue;
256
struct timeval tv, *tp;
217
ngx_event_t *ev, **queue;
218
struct timeval tv, *tp;
260
221
if (max_fd == -1) {
261
222
for (i = 0; i < nevents; i++) {
302
259
work_read_fd_set = master_read_fd_set;
303
260
work_write_fd_set = master_write_fd_set;
306
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
308
* (void *) disables "dereferencing type-punned
309
* pointer will break strict-aliasing rules
311
"select read fd_set: %08Xd",
312
*(int *) (void *) &work_read_fd_set);
317
ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
321
262
ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp);
326
err = ngx_socket_errno;
331
if (flags & NGX_UPDATE_TIME) {
332
ngx_time_update(0, 0);
264
err = (ready == -1) ? ngx_errno : 0;
266
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
335
270
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
336
271
"select ready %d", ready);
341
ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed");
348
274
ngx_uint_t level;
363
289
ngx_log_error(level, cycle->log, err, "select() failed");
292
ngx_select_repair_fd_sets(cycle);
364
295
return NGX_ERROR;
369
298
if (ready == 0) {
370
299
if (timer != NGX_TIMER_INFINITE) {
414
343
ngx_mutex_unlock(ngx_posted_events_mutex);
416
345
if (ready != nready) {
417
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events");
346
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
347
"select ready != events: %d:%d", ready, nready);
349
ngx_select_repair_fd_sets(cycle);
357
ngx_select_repair_fd_sets(ngx_cycle_t *cycle)
364
for (s = 0; s <= max_fd; s++) {
366
if (FD_ISSET(s, &master_read_fd_set) == 0) {
372
if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
373
err = ngx_socket_errno;
375
ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
376
"invalid descriptor #%d in read fd_set", s);
378
FD_CLR(s, &master_read_fd_set);
382
for (s = 0; s <= max_fd; s++) {
384
if (FD_ISSET(s, &master_write_fd_set) == 0) {
390
if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
391
err = ngx_socket_errno;
393
ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
394
"invalid descriptor #%d in write fd_set", s);
396
FD_CLR(s, &master_write_fd_set);
425
405
ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
435
415
/* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */
439
if ((unsigned) ecf->connections > FD_SETSIZE) {
417
if (cycle->connection_n > FD_SETSIZE) {
440
418
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
441
419
"the maximum number of files "
442
"supported by select() is " ngx_value(FD_SETSIZE));
420
"supported by select() is %ud", FD_SETSIZE);
443
421
return NGX_CONF_ERROR;
448
#if (NGX_THREADS) && !(NGX_WIN32)
450
426
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
451
427
"select() is not supported in the threaded mode");