~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/event/modules/ngx_select_module.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
9
10
#include <ngx_event.h>
10
11
 
11
12
 
12
 
 
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,
18
18
    ngx_uint_t flags);
19
19
static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
20
20
    ngx_uint_t flags);
 
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);
22
23
 
23
24
 
26
27
static fd_set         work_read_fd_set;
27
28
static fd_set         work_write_fd_set;
28
29
 
29
 
#if (NGX_WIN32)
30
 
static ngx_uint_t     max_read;
31
 
static ngx_uint_t     max_write;
32
 
#else
33
30
static ngx_int_t      max_fd;
34
 
#endif
35
 
 
36
31
static ngx_uint_t     nevents;
37
32
 
38
33
static ngx_event_t  **event_index;
87
82
        nevents = 0;
88
83
    }
89
84
 
90
 
    if (ngx_process == NGX_PROCESS_WORKER
 
85
    if (ngx_process >= NGX_PROCESS_WORKER
91
86
        || cycle->old_cycle == NULL
92
87
        || cycle->old_cycle->connection_n < cycle->connection_n)
93
88
    {
111
106
 
112
107
    ngx_event_flags = NGX_USE_LEVEL_EVENT;
113
108
 
114
 
#if (NGX_WIN32)
115
 
    max_read = max_write = 0;
116
 
#else
117
109
    max_fd = -1;
118
 
#endif
119
110
 
120
111
    return NGX_OK;
121
112
}
146
137
        return NGX_OK;
147
138
    }
148
139
 
149
 
#if (NGX_WIN32)
150
 
 
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))
153
142
    {
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;
158
147
    }
159
148
 
160
149
    if (event == NGX_READ_EVENT) {
161
150
        FD_SET(c->fd, &master_read_fd_set);
162
 
        max_read++;
163
 
 
164
 
    } else if (event == NGX_WRITE_EVENT) {
165
 
        FD_SET(c->fd, &master_write_fd_set);
166
 
        max_write++;
167
 
    }
168
 
 
169
 
#else
170
 
 
171
 
    if (event == NGX_READ_EVENT) {
172
 
        FD_SET(c->fd, &master_read_fd_set);
173
151
 
174
152
    } else if (event == NGX_WRITE_EVENT) {
175
153
        FD_SET(c->fd, &master_write_fd_set);
179
157
        max_fd = c->fd;
180
158
    }
181
159
 
182
 
#endif
183
 
 
184
160
    ev->active = 1;
185
161
 
186
162
    event_index[nevents] = ev;
194
170
static ngx_int_t
195
171
ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
196
172
{
 
173
    ngx_event_t       *e;
197
174
    ngx_connection_t  *c;
198
175
 
199
176
    c = ev->data;
207
184
    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
208
185
                   "select del event fd:%d ev:%i", c->fd, event);
209
186
 
210
 
#if (NGX_WIN32)
211
 
 
212
 
    if (event == NGX_READ_EVENT) {
213
 
        FD_CLR(c->fd, &master_read_fd_set);
214
 
        max_read--;
215
 
 
216
 
    } else if (event == NGX_WRITE_EVENT) {
217
 
        FD_CLR(c->fd, &master_write_fd_set);
218
 
        max_write--;
219
 
    }
220
 
 
221
 
#else
222
 
 
223
187
    if (event == NGX_READ_EVENT) {
224
188
        FD_CLR(c->fd, &master_read_fd_set);
225
189
 
231
195
        max_fd = -1;
232
196
    }
233
197
 
234
 
#endif
235
 
 
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;
239
202
    }
240
203
 
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)
250
213
{
251
 
    int                 ready, nready;
252
 
    ngx_uint_t          i, found;
253
 
    ngx_err_t           err;
254
 
    ngx_event_t        *ev, **queue;
255
 
    ngx_connection_t   *c;
256
 
    struct timeval      tv, *tp;
257
 
 
258
 
#if !(NGX_WIN32)
 
214
    int                ready, nready;
 
215
    ngx_err_t          err;
 
216
    ngx_uint_t         i, found;
 
217
    ngx_event_t       *ev, **queue;
 
218
    struct timeval     tv, *tp;
 
219
    ngx_connection_t  *c;
259
220
 
260
221
    if (max_fd == -1) {
261
222
        for (i = 0; i < nevents; i++) {
269
230
                       "change max_fd: %d", max_fd);
270
231
    }
271
232
 
272
 
#endif
273
 
 
274
233
#if (NGX_DEBUG)
275
234
    if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
276
235
        for (i = 0; i < nevents; i++) {
280
239
                           "select event: fd:%d wr:%d", c->fd, ev->write);
281
240
        }
282
241
 
283
 
#if !(NGX_WIN32)
284
242
        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
285
243
                       "max_fd: %d", max_fd);
286
 
#endif
287
244
    }
288
245
#endif
289
246
 
302
259
    work_read_fd_set = master_read_fd_set;
303
260
    work_write_fd_set = master_write_fd_set;
304
261
 
305
 
#if 1
306
 
    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
307
 
                   /*
308
 
                    * (void *) disables "dereferencing type-punned
309
 
                    * pointer will break strict-aliasing rules
310
 
                    */
311
 
                   "select read fd_set: %08Xd",
312
 
                   *(int *) (void *) &work_read_fd_set);
313
 
#endif
314
 
 
315
 
#if (NGX_WIN32)
316
 
 
317
 
    ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
318
 
 
319
 
#else
320
 
 
321
262
    ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp);
322
263
 
323
 
#endif
324
 
 
325
 
    if (ready == -1) {
326
 
        err = ngx_socket_errno;
327
 
    } else {
328
 
        err = 0;
329
 
    }
330
 
 
331
 
    if (flags & NGX_UPDATE_TIME) {
332
 
        ngx_time_update(0, 0);
 
264
    err = (ready == -1) ? ngx_errno : 0;
 
265
 
 
266
    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
 
267
        ngx_time_update();
333
268
    }
334
269
 
335
270
    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
336
271
                   "select ready %d", ready);
337
272
 
338
 
#if (NGX_WIN32)
339
 
 
340
 
    if (err) {
341
 
        ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed");
342
 
        return NGX_ERROR;
343
 
    }
344
 
 
345
 
#else
346
 
 
347
273
    if (err) {
348
274
        ngx_uint_t  level;
349
275
 
361
287
        }
362
288
 
363
289
        ngx_log_error(level, cycle->log, err, "select() failed");
 
290
 
 
291
        if (err == EBADF) {
 
292
            ngx_select_repair_fd_sets(cycle);
 
293
        }
 
294
 
364
295
        return NGX_ERROR;
365
296
    }
366
297
 
367
 
#endif
368
 
 
369
298
    if (ready == 0) {
370
299
        if (timer != NGX_TIMER_INFINITE) {
371
300
            return NGX_OK;
414
343
    ngx_mutex_unlock(ngx_posted_events_mutex);
415
344
 
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);
 
348
 
 
349
        ngx_select_repair_fd_sets(cycle);
418
350
    }
419
351
 
420
352
    return NGX_OK;
421
353
}
422
354
 
423
355
 
 
356
static void
 
357
ngx_select_repair_fd_sets(ngx_cycle_t *cycle)
 
358
{
 
359
    int           n;
 
360
    socklen_t     len;
 
361
    ngx_err_t     err;
 
362
    ngx_socket_t  s;
 
363
 
 
364
    for (s = 0; s <= max_fd; s++) {
 
365
 
 
366
        if (FD_ISSET(s, &master_read_fd_set) == 0) {
 
367
            continue;
 
368
        }
 
369
 
 
370
        len = sizeof(int);
 
371
 
 
372
        if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
 
373
            err = ngx_socket_errno;
 
374
 
 
375
            ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
 
376
                          "invalid descriptor #%d in read fd_set", s);
 
377
 
 
378
            FD_CLR(s, &master_read_fd_set);
 
379
        }
 
380
    }
 
381
 
 
382
    for (s = 0; s <= max_fd; s++) {
 
383
 
 
384
        if (FD_ISSET(s, &master_write_fd_set) == 0) {
 
385
            continue;
 
386
        }
 
387
 
 
388
        len = sizeof(int);
 
389
 
 
390
        if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
 
391
            err = ngx_socket_errno;
 
392
 
 
393
            ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
 
394
                          "invalid descriptor #%d in write fd_set", s);
 
395
 
 
396
            FD_CLR(s, &master_write_fd_set);
 
397
        }
 
398
    }
 
399
 
 
400
    max_fd = -1;
 
401
}
 
402
 
 
403
 
424
404
static char *
425
405
ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
426
406
{
434
414
 
435
415
    /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */
436
416
 
437
 
#if !(NGX_WIN32)
438
 
 
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;
444
422
    }
445
423
 
446
 
#endif
447
 
 
448
 
#if (NGX_THREADS) && !(NGX_WIN32)
 
424
#if (NGX_THREADS)
449
425
 
450
426
    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
451
427
                  "select() is not supported in the threaded mode");