~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/event/ngx_event.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_event.h>
 10 
 11 
 12 #define DEFAULT_CONNECTIONS  512
 13 
 14 
 15 extern ngx_module_t ngx_kqueue_module;
 16 extern ngx_module_t ngx_eventport_module;
 17 extern ngx_module_t ngx_devpoll_module;
 18 extern ngx_module_t ngx_epoll_module;
 19 extern ngx_module_t ngx_rtsig_module;
 20 extern ngx_module_t ngx_select_module;
 21 
 22 
 23 static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
 24 static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
 25 static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 26 
 27 static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
 28     void *conf);
 29 static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 30 static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
 31     void *conf);
 32 
 33 static void *ngx_event_create_conf(ngx_cycle_t *cycle);
 34 static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
 35 
 36 
 37 static ngx_uint_t     ngx_timer_resolution;
 38 sig_atomic_t          ngx_event_timer_alarm;
 39 
 40 static ngx_uint_t     ngx_event_max_module;
 41 
 42 ngx_uint_t            ngx_event_flags;
 43 ngx_event_actions_t   ngx_event_actions;
 44 
 45 
 46 static ngx_atomic_t   connection_counter = 1;
 47 ngx_atomic_t         *ngx_connection_counter = &connection_counter;
 48 
 49 
 50 ngx_atomic_t         *ngx_accept_mutex_ptr;
 51 ngx_shmtx_t           ngx_accept_mutex;
 52 ngx_uint_t            ngx_use_accept_mutex;
 53 ngx_uint_t            ngx_accept_events;
 54 ngx_uint_t            ngx_accept_mutex_held;
 55 ngx_msec_t            ngx_accept_mutex_delay;
 56 ngx_int_t             ngx_accept_disabled;
 57 ngx_file_t            ngx_accept_mutex_lock_file;
 58 
 59 
 60 #if (NGX_STAT_STUB)
 61 
 62 ngx_atomic_t   ngx_stat_accepted0;
 63 ngx_atomic_t  *ngx_stat_accepted = &ngx_stat_accepted0;
 64 ngx_atomic_t   ngx_stat_handled0;
 65 ngx_atomic_t  *ngx_stat_handled = &ngx_stat_handled0;
 66 ngx_atomic_t   ngx_stat_requests0;
 67 ngx_atomic_t  *ngx_stat_requests = &ngx_stat_requests0;
 68 ngx_atomic_t   ngx_stat_active0;
 69 ngx_atomic_t  *ngx_stat_active = &ngx_stat_active0;
 70 ngx_atomic_t   ngx_stat_reading0;
 71 ngx_atomic_t  *ngx_stat_reading = &ngx_stat_reading0;
 72 ngx_atomic_t   ngx_stat_writing0;
 73 ngx_atomic_t  *ngx_stat_writing = &ngx_stat_writing0;
 74 
 75 #endif
 76 
 77 
 78 
 79 static ngx_command_t  ngx_events_commands[] = {
 80 
 81     { ngx_string("events"),
 82       NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
 83       ngx_events_block,
 84       0,
 85       0,
 86       NULL },
 87 
 88       ngx_null_command
 89 };
 90 
 91 
 92 static ngx_core_module_t  ngx_events_module_ctx = {
 93     ngx_string("events"),
 94     NULL,
 95     NULL
 96 };
 97 
 98 
 99 ngx_module_t  ngx_events_module = {
100     NGX_MODULE_V1,
101     &ngx_events_module_ctx,                /* module context */
102     ngx_events_commands,                   /* module directives */
103     NGX_CORE_MODULE,                       /* module type */
104     NULL,                                  /* init master */
105     NULL,                                  /* init module */
106     NULL,                                  /* init process */
107     NULL,                                  /* init thread */
108     NULL,                                  /* exit thread */
109     NULL,                                  /* exit process */
110     NULL,                                  /* exit master */
111     NGX_MODULE_V1_PADDING
112 };
113 
114 
115 static ngx_str_t  event_core_name = ngx_string("event_core");
116 
117 
118 static ngx_command_t  ngx_event_core_commands[] = {
119 
120     { ngx_string("worker_connections"),
121       NGX_EVENT_CONF|NGX_CONF_TAKE1,
122       ngx_event_connections,
123       0,
124       0,
125       NULL },
126 
127     { ngx_string("connections"),
128       NGX_EVENT_CONF|NGX_CONF_TAKE1,
129       ngx_event_connections,
130       0,
131       0,
132       NULL },
133 
134     { ngx_string("use"),
135       NGX_EVENT_CONF|NGX_CONF_TAKE1,
136       ngx_event_use,
137       0,
138       0,
139       NULL },
140 
141     { ngx_string("multi_accept"),
142       NGX_EVENT_CONF|NGX_CONF_FLAG,
143       ngx_conf_set_flag_slot,
144       0,
145       offsetof(ngx_event_conf_t, multi_accept),
146       NULL },
147 
148     { ngx_string("accept_mutex"),
149       NGX_EVENT_CONF|NGX_CONF_FLAG,
150       ngx_conf_set_flag_slot,
151       0,
152       offsetof(ngx_event_conf_t, accept_mutex),
153       NULL },
154 
155     { ngx_string("accept_mutex_delay"),
156       NGX_EVENT_CONF|NGX_CONF_TAKE1,
157       ngx_conf_set_msec_slot,
158       0,
159       offsetof(ngx_event_conf_t, accept_mutex_delay),
160       NULL },
161 
162     { ngx_string("debug_connection"),
163       NGX_EVENT_CONF|NGX_CONF_TAKE1,
164       ngx_event_debug_connection,
165       0,
166       0,
167       NULL },
168 
169       ngx_null_command
170 };
171 
172 
173 ngx_event_module_t  ngx_event_core_module_ctx = {
174     &event_core_name,
175     ngx_event_create_conf,                 /* create configuration */
176     ngx_event_init_conf,                   /* init configuration */
177 
178     { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
179 };
180 
181 
182 ngx_module_t  ngx_event_core_module = {
183     NGX_MODULE_V1,
184     &ngx_event_core_module_ctx,            /* module context */
185     ngx_event_core_commands,               /* module directives */
186     NGX_EVENT_MODULE,                      /* module type */
187     NULL,                                  /* init master */
188     ngx_event_module_init,                 /* init module */
189     ngx_event_process_init,                /* init process */
190     NULL,                                  /* init thread */
191     NULL,                                  /* exit thread */
192     NULL,                                  /* exit process */
193     NULL,                                  /* exit master */
194     NGX_MODULE_V1_PADDING
195 };
196 
197 
198 void
199 ngx_process_events_and_timers(ngx_cycle_t *cycle)
200 {
201     ngx_uint_t  flags;
202     ngx_msec_t  timer, delta;
203 
204     if (ngx_timer_resolution) {
205         timer = NGX_TIMER_INFINITE;
206         flags = 0;
207 
208     } else {
209         timer = ngx_event_find_timer();
210         flags = NGX_UPDATE_TIME;
211 
212 #if (NGX_THREADS)
213 
214         if (timer == NGX_TIMER_INFINITE || timer > 500) {
215             timer = 500;
216         }
217 
218 #endif
219     }
220 
221     if (ngx_use_accept_mutex) {
222         if (ngx_accept_disabled > 0) {
223             ngx_accept_disabled--;
224 
225         } else {
226             if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
227                 return;
228             }
229 
230             if (ngx_accept_mutex_held) {
231                 flags |= NGX_POST_EVENTS;
232 
233             } else {
234                 if (timer == NGX_TIMER_INFINITE
235                     || timer > ngx_accept_mutex_delay)
236                 {
237                     timer = ngx_accept_mutex_delay;
238                 }
239             }
240         }
241     }
242 
243     delta = ngx_current_msec;
244 
245     (void) ngx_process_events(cycle, timer, flags);
246 
247     delta = ngx_current_msec - delta;
248 
249     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
250                    "timer delta: %M", delta);
251 
252     if (ngx_posted_accept_events) {
253         ngx_event_process_posted(cycle, &ngx_posted_accept_events);
254     }
255 
256     if (ngx_accept_mutex_held) {
257         ngx_shmtx_unlock(&ngx_accept_mutex);
258     }
259 
260     if (delta) {
261         ngx_event_expire_timers();
262     }
263 
264     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
265                    "posted events %p", ngx_posted_events);
266 
267     if (ngx_posted_events) {
268         if (ngx_threaded) {
269             ngx_wakeup_worker_thread(cycle);
270 
271         } else {
272             ngx_event_process_posted(cycle, &ngx_posted_events);
273         }
274     }
275 }
276 
277 
278 ngx_int_t
279 ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
280 {
281     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
282 
283         /* kqueue, epoll */
284 
285         if (!rev->active && !rev->ready) {
286             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
287                 == NGX_ERROR)
288             {
289                 return NGX_ERROR;
290             }
291         }
292 
293         return NGX_OK;
294 
295     } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
296 
297         /* select, poll, /dev/poll */
298 
299         if (!rev->active && !rev->ready) {
300             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
301                 == NGX_ERROR)
302             {
303                 return NGX_ERROR;
304             }
305 
306             return NGX_OK;
307         }
308 
309         if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
310             if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags)
311                 == NGX_ERROR)
312             {
313                 return NGX_ERROR;
314             }
315 
316             return NGX_OK;
317         }
318 
319     } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
320 
321         /* event ports */
322 
323         if (!rev->active && !rev->ready) {
324             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
325                 return NGX_ERROR;
326             }
327 
328             return NGX_OK;
329         }
330 
331         if (rev->oneshot && !rev->ready) {
332             if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
333                 return NGX_ERROR;
334             }
335 
336             return NGX_OK;
337         }
338     }
339 
340     /* aio, iocp, rtsig */
341 
342     return NGX_OK;
343 }
344 
345 
346 ngx_int_t
347 ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
348 {
349     ngx_connection_t  *c;
350 
351     if (lowat) {
352         c = wev->data;
353 
354         if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
355             return NGX_ERROR;
356         }
357     }
358 
359     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
360 
361         /* kqueue, epoll */
362 
363         if (!wev->active && !wev->ready) {
364             if (ngx_add_event(wev, NGX_WRITE_EVENT,
365                               NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
366                 == NGX_ERROR)
367             {
368                 return NGX_ERROR;
369             }
370         }
371 
372         return NGX_OK;
373 
374     } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
375 
376         /* select, poll, /dev/poll */
377 
378         if (!wev->active && !wev->ready) {
379             if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
380                 == NGX_ERROR)
381             {
382                 return NGX_ERROR;
383             }
384 
385             return NGX_OK;
386         }
387 
388         if (wev->active && wev->ready) {
389             if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
390                 == NGX_ERROR)
391             {
392                 return NGX_ERROR;
393             }
394 
395             return NGX_OK;
396         }
397 
398     } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
399 
400         /* event ports */
401 
402         if (!wev->active && !wev->ready) {
403             if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
404                 return NGX_ERROR;
405             }
406 
407             return NGX_OK;
408         }
409 
410         if (wev->oneshot && wev->ready) {
411             if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
412                 return NGX_ERROR;
413             }
414 
415             return NGX_OK;
416         }
417     }
418 
419     /* aio, iocp, rtsig */
420 
421     return NGX_OK;
422 }
423 
424 
425 static ngx_int_t
426 ngx_event_module_init(ngx_cycle_t *cycle)
427 {
428     void              ***cf;
429     u_char              *shared;
430     size_t               size, cl;
431     ngx_shm_t            shm;
432     ngx_time_t          *tp;
433     ngx_core_conf_t     *ccf;
434     ngx_event_conf_t    *ecf;
435 
436     cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
437 
438     if (cf == NULL) {
439         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
440                       "no \"events\" section in configuration");
441         return NGX_ERROR;
442     }
443 
444     ecf = (*cf)[ngx_event_core_module.ctx_index];
445 
446     if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) {
447         ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
448                       "using the \"%s\" event method", ecf->name);
449     }
450 
451     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
452 
453     ngx_timer_resolution = ccf->timer_resolution;
454 
455 #if !(NGX_WIN32)
456     {
457     ngx_int_t      limit;
458     struct rlimit  rlmt;
459 
460     if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
461         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
462                       "getrlimit(RLIMIT_NOFILE) failed, ignored");
463 
464     } else {
465         if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur
466             && (ccf->rlimit_nofile == NGX_CONF_UNSET
467                 || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile))
468         {
469             limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?
470                          (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile;
471 
472             ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
473                           "%ui worker_connections are more than "
474                           "open file resource limit: %i",
475                           ecf->connections, limit);
476         }
477     }
478     }
479 #endif /* !(NGX_WIN32) */
480 
481 
482     if (ccf->master == 0) {
483         return NGX_OK;
484     }
485 
486     if (ngx_accept_mutex_ptr) {
487         return NGX_OK;
488     }
489 
490 
491     /* cl should be equal or bigger than cache line size */
492 
493     cl = 128;
494 
495     size = cl            /* ngx_accept_mutex */
496            + cl          /* ngx_connection_counter */
497            + cl;         /* ngx_temp_number */
498 
499 #if (NGX_STAT_STUB)
500 
501     size += cl           /* ngx_stat_accepted */
502            + cl          /* ngx_stat_handled */
503            + cl          /* ngx_stat_requests */
504            + cl          /* ngx_stat_active */
505            + cl          /* ngx_stat_reading */
506            + cl;         /* ngx_stat_writing */
507 
508 #endif
509 
510     shm.size = size;
511     shm.name.len = sizeof("nginx_shared_zone");
512     shm.name.data = (u_char *) "nginx_shared_zone";
513     shm.log = cycle->log;
514 
515     if (ngx_shm_alloc(&shm) != NGX_OK) {
516         return NGX_ERROR;
517     }
518 
519     shared = shm.addr;
520 
521     ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
522 
523     if (ngx_shmtx_create(&ngx_accept_mutex, shared, cycle->lock_file.data)
524         != NGX_OK)
525     {
526         return NGX_ERROR;
527     }
528 
529     ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
530 
531     (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
532 
533     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
534                    "counter: %p, %d",
535                    ngx_connection_counter, *ngx_connection_counter);
536 
537     ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
538 
539     tp = ngx_timeofday();
540 
541     ngx_random_number = (tp->msec << 16) + ngx_pid;
542 
543 #if (NGX_STAT_STUB)
544 
545     ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
546     ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
547     ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
548     ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
549     ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
550     ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
551 
552 #endif
553 
554     return NGX_OK;
555 }
556 
557 
558 #if !(NGX_WIN32)
559 
560 void
561 ngx_timer_signal_handler(int signo)
562 {
563     ngx_event_timer_alarm = 1;
564 
565     ngx_time_update(0, 0);
566 
567 #if 1
568     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
569 #endif
570 }
571 
572 #endif
573 
574 
575 static ngx_int_t
576 ngx_event_process_init(ngx_cycle_t *cycle)
577 {
578     ngx_uint_t           m, i;
579     ngx_event_t         *rev, *wev;
580     ngx_listening_t     *ls;
581     ngx_connection_t    *c, *next, *old;
582     ngx_core_conf_t     *ccf;
583     ngx_event_conf_t    *ecf;
584     ngx_event_module_t  *module;
585 
586     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
587     ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
588 
589     if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
590         ngx_use_accept_mutex = 1;
591         ngx_accept_mutex_held = 0;
592         ngx_accept_mutex_delay = ecf->accept_mutex_delay;
593 
594     } else {
595         ngx_use_accept_mutex = 0;
596     }
597 
598 #if (NGX_THREADS)
599     ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
600     if (ngx_posted_events_mutex == NULL) {
601         return NGX_ERROR;
602     }
603 #endif
604 
605     if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
606         return NGX_ERROR;
607     }
608 
609     for (m = 0; ngx_modules[m]; m++) {
610         if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
611             continue;
612         }
613 
614         if (ngx_modules[m]->ctx_index != ecf->use) {
615             continue;
616         }
617 
618         module = ngx_modules[m]->ctx;
619 
620         if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
621             /* fatal */
622             exit(2);
623         }
624 
625         break;
626     }
627 
628 #if !(NGX_WIN32)
629 
630     if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
631         struct sigaction  sa;
632         struct itimerval  itv;
633 
634         ngx_memzero(&sa, sizeof(struct sigaction));
635         sa.sa_handler = ngx_timer_signal_handler;
636         sigemptyset(&sa.sa_mask);
637 
638         if (sigaction(SIGALRM, &sa, NULL) == -1) {
639             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
640                           "sigaction(SIGALRM) failed");
641             return NGX_ERROR;
642         }
643 
644         itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
645         itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
646         itv.it_value.tv_sec = ngx_timer_resolution / 1000;
647         itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;
648 
649         if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
650             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
651                           "setitimer() failed");
652         }
653     }
654 
655     if (ngx_event_flags & NGX_USE_FD_EVENT) {
656         struct rlimit  rlmt;
657 
658         if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
659             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
660                           "getrlimit(RLIMIT_NOFILE) failed");
661             return NGX_ERROR;
662         }
663 
664         cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;
665 
666         cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
667                                   cycle->log);
668         if (cycle->files == NULL) {
669             return NGX_ERROR;
670         }
671     }
672 
673 #endif
674 
675     cycle->connections =
676         ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
677     if (cycle->connections == NULL) {
678         return NGX_ERROR;
679     }
680 
681     c = cycle->connections;
682 
683     cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
684                                    cycle->log);
685     if (cycle->read_events == NULL) {
686         return NGX_ERROR;
687     }
688 
689     rev = cycle->read_events;
690     for (i = 0; i < cycle->connection_n; i++) {
691         rev[i].closed = 1;
692         rev[i].instance = 1;
693 #if (NGX_THREADS)
694         rev[i].lock = &c[i].lock;
695         rev[i].own_lock = &c[i].lock;
696 #endif
697     }
698 
699     cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
700                                     cycle->log);
701     if (cycle->write_events == NULL) {
702         return NGX_ERROR;
703     }
704 
705     wev = cycle->write_events;
706     for (i = 0; i < cycle->connection_n; i++) {
707         wev[i].closed = 1;
708 #if (NGX_THREADS)
709         wev[i].lock = &c[i].lock;
710         wev[i].own_lock = &c[i].lock;
711 #endif
712     }
713 
714     i = cycle->connection_n;
715     next = NULL;
716 
717     do {
718         i--;
719 
720         c[i].data = next;
721         c[i].read = &cycle->read_events[i];
722         c[i].write = &cycle->write_events[i];
723         c[i].fd = (ngx_socket_t) -1;
724 
725         next = &c[i];
726 
727 #if (NGX_THREADS)
728         c[i].lock = 0;
729 #endif
730     } while (i);
731 
732     cycle->free_connections = next;
733     cycle->free_connection_n = cycle->connection_n;
734 
735     /* for each listening socket */
736 
737     ls = cycle->listening.elts;
738     for (i = 0; i < cycle->listening.nelts; i++) {
739 
740         c = ngx_get_connection(ls[i].fd, cycle->log);
741 
742         if (c == NULL) {
743             return NGX_ERROR;
744         }
745 
746         c->log = &ls[i].log;
747 
748         c->listening = &ls[i];
749         ls[i].connection = c;
750 
751         rev = c->read;
752 
753         rev->log = c->log;
754         rev->accept = 1;
755 
756 #if (NGX_HAVE_DEFERRED_ACCEPT)
757         rev->deferred_accept = ls[i].deferred_accept;
758 #endif
759 
760         if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
761             if (ls[i].previous) {
762 
763                 /*
764                  * delete the old accept events that were bound to
765                  * the old cycle read events array
766                  */
767 
768                 old = ls[i].previous->connection;
769 
770                 if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
771                     == NGX_ERROR)
772                 {
773                     return NGX_ERROR;
774                 }
775 
776                 old->fd = (ngx_socket_t) -1;
777             }
778         }
779 
780 #if (NGX_WIN32)
781 
782         if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
783             ngx_iocp_conf_t  *iocpcf;
784 
785             rev->handler = ngx_event_acceptex;
786 
787             if (ngx_use_accept_mutex) {
788                 continue;
789             }
790 
791             if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
792                 return NGX_ERROR;
793             }
794 
795             ls[i].log.handler = ngx_acceptex_log_error;
796 
797             iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
798             if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
799                 == NGX_ERROR)
800             {
801                 return NGX_ERROR;
802             }
803 
804         } else {
805             rev->handler = ngx_event_accept;
806 
807             if (ngx_use_accept_mutex) {
808                 continue;
809             }
810 
811             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
812                 return NGX_ERROR;
813             }
814         }
815 
816 #else
817 
818         rev->handler = ngx_event_accept;
819 
820         if (ngx_use_accept_mutex) {
821             continue;
822         }
823 
824         if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
825             if (ngx_add_conn(c) == NGX_ERROR) {
826                 return NGX_ERROR;
827             }
828 
829         } else {
830             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
831                 return NGX_ERROR;
832             }
833         }
834 
835 #endif
836 
837     }
838 
839     return NGX_OK;
840 }
841 
842 
843 ngx_int_t
844 ngx_send_lowat(ngx_connection_t *c, size_t lowat)
845 {
846     int  sndlowat;
847 
848 #if (NGX_HAVE_LOWAT_EVENT)
849 
850     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
851         c->write->available = lowat;
852         return NGX_OK;
853     }
854 
855 #endif
856 
857     if (lowat == 0 || c->sndlowat) {
858         return NGX_OK;
859     }
860 
861     sndlowat = (int) lowat;
862 
863     if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
864                    (const void *) &sndlowat, sizeof(int))
865         == -1)
866     {
867         ngx_connection_error(c, ngx_socket_errno,
868                              "setsockopt(SO_SNDLOWAT) failed");
869         return NGX_ERROR;
870     }
871 
872     c->sndlowat = 1;
873 
874     return NGX_OK;
875 }
876 
877 
878 static char *
879 ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
880 {
881     char                 *rv;
882     void               ***ctx;
883     ngx_uint_t            i;
884     ngx_conf_t            pcf;
885     ngx_event_module_t   *m;
886 
887     /* count the number of the event modules and set up their indices */
888 
889     ngx_event_max_module = 0;
890     for (i = 0; ngx_modules[i]; i++) {
891         if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
892             continue;
893         }
894 
895         ngx_modules[i]->ctx_index = ngx_event_max_module++;
896     }
897 
898     ctx = ngx_pcalloc(cf->pool, sizeof(void *));
899     if (ctx == NULL) {
900         return NGX_CONF_ERROR;
901     }
902 
903     *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
904     if (*ctx == NULL) {
905         return NGX_CONF_ERROR;
906     }
907 
908     *(void **) conf = ctx;
909 
910     for (i = 0; ngx_modules[i]; i++) {
911         if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
912             continue;
913         }
914 
915         m = ngx_modules[i]->ctx;
916 
917         if (m->create_conf) {
918             (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
919             if ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
920                 return NGX_CONF_ERROR;
921             }
922         }
923     }
924 
925     pcf = *cf;
926     cf->ctx = ctx;
927     cf->module_type = NGX_EVENT_MODULE;
928     cf->cmd_type = NGX_EVENT_CONF;
929 
930     rv = ngx_conf_parse(cf, NULL);
931 
932     *cf = pcf;
933 
934     if (rv != NGX_CONF_OK)
935         return rv;
936 
937     for (i = 0; ngx_modules[i]; i++) {
938         if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
939             continue;
940         }
941 
942         m = ngx_modules[i]->ctx;
943 
944         if (m->init_conf) {
945             rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]);
946             if (rv != NGX_CONF_OK) {
947                 return rv;
948             }
949         }
950     }
951 
952     return NGX_CONF_OK;
953 }
954 
955 
956 static char *
957 ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
958 {
959     ngx_event_conf_t  *ecf = conf;
960 
961     ngx_str_t  *value;
962 
963     if (ecf->connections != NGX_CONF_UNSET_UINT) {
964         return "is duplicate";
965     }
966 
967     if (ngx_strcmp(cmd->name.data, "connections") == 0) {
968         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
969                            "the \"connections\" directive is deprecated, "
970                            "use the \"worker_connections\" directive instead");
971     }
972 
973     value = cf->args->elts;
974     ecf->connections = ngx_atoi(value[1].data, value[1].len);
975     if (ecf->connections == (ngx_uint_t) NGX_ERROR) {
976         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
977                            "invalid number \"%V\"", &value[1]);
978 
979         return NGX_CONF_ERROR;
980     }
981 
982     cf->cycle->connection_n = ecf->connections;
983 
984     return NGX_CONF_OK;
985 }
986 
987 
988 static char *
989 ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
990 {
991     ngx_event_conf_t  *ecf = conf;
992 
993     ngx_int_t             m;
994     ngx_str_t            *value;
995     ngx_event_conf_t     *old_ecf;
996     ngx_event_module_t   *module;
997 
998     if (ecf->use != NGX_CONF_UNSET_UINT) {
999         return "is duplicate";
1000     }
1001 
1002     value = cf->args->elts;
1003 
1004     if (cf->cycle->old_cycle->conf_ctx) {
1005         old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx,
1006                                      ngx_event_core_module);
1007     } else {
1008         old_ecf = NULL;
1009     }
1010 
1011 
1012     for (m = 0; ngx_modules[m]; m++) {
1013         if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
1014             continue;
1015         }
1016 
1017         module = ngx_modules[m]->ctx;
1018         if (module->name->len == value[1].len) {
1019             if (ngx_strcmp(module->name->data, value[1].data) == 0) {
1020                 ecf->use = ngx_modules[m]->ctx_index;
1021                 ecf->name = module->name->data;
1022 
1023                 if (ngx_process == NGX_PROCESS_SINGLE
1024                     && old_ecf
1025                     && old_ecf->use != ecf->use)
1026                 {
1027                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1028                                "when the server runs without a master process "
1029                                "the \"%V\" event type must be the same as "
1030                                "in previous configuration - \"%s\" "
1031                                "and it can not be changed on the fly, "
1032                                "to change it you need to stop server "
1033                                "and start it again",
1034                                &value[1], old_ecf->name);
1035 
1036                     return NGX_CONF_ERROR;
1037                 }
1038 
1039                 return NGX_CONF_OK;
1040             }
1041         }
1042     }
1043 
1044     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1045                        "invalid event type \"%V\"", &value[1]);
1046 
1047     return NGX_CONF_ERROR;
1048 }
1049 
1050 
1051 static char *
1052 ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1053 {
1054 #if (NGX_DEBUG)
1055     ngx_event_conf_t  *ecf = conf;
1056 
1057     ngx_int_t           rc;
1058     ngx_str_t          *value;
1059     ngx_event_debug_t  *dc;
1060     struct hostent     *h;
1061     ngx_cidr_t          cidr;
1062 
1063     value = cf->args->elts;
1064 
1065     dc = ngx_array_push(&ecf->debug_connection);
1066     if (dc == NULL) {
1067         return NGX_CONF_ERROR;
1068     }
1069 
1070     rc = ngx_ptocidr(&value[1], &cidr);
1071 
1072     if (rc == NGX_DONE) {
1073         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1074                            "low address bits of %V are meaningless", &value[1]);
1075         rc = NGX_OK;
1076     }
1077 
1078     if (rc == NGX_OK) {
1079 
1080         /* AF_INET only */
1081 
1082         if (cidr.family != AF_INET) {
1083             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1084                                "\"debug_connection\" supports IPv4 only");
1085             return NGX_CONF_ERROR;
1086         }
1087 
1088         dc->mask = cidr.u.in.mask;
1089         dc->addr = cidr.u.in.addr;
1090 
1091         return NGX_CONF_OK;
1092     }
1093 
1094     h = gethostbyname((char *) value[1].data);
1095 
1096     if (h == NULL || h->h_addr_list[0] == NULL) {
1097         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1098                            "host \"%s\" not found", value[1].data);
1099         return NGX_CONF_ERROR;
1100     }
1101 
1102     dc->mask = 0xffffffff;
1103     dc->addr = *(in_addr_t *)(h->h_addr_list[0]);
1104 
1105 #else
1106 
1107     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1108                        "\"debug_connection\" is ignored, you need to rebuild "
1109                        "nginx using --with-debug option to enable it");
1110 
1111 #endif
1112 
1113     return NGX_CONF_OK;
1114 }
1115 
1116 
1117 static void *
1118 ngx_event_create_conf(ngx_cycle_t *cycle)
1119 {
1120     ngx_event_conf_t  *ecf;
1121 
1122     ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
1123     if (ecf == NULL) {
1124         return NULL;
1125     }
1126 
1127     ecf->connections = NGX_CONF_UNSET_UINT;
1128     ecf->use = NGX_CONF_UNSET_UINT;
1129     ecf->multi_accept = NGX_CONF_UNSET;
1130     ecf->accept_mutex = NGX_CONF_UNSET;
1131     ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
1132     ecf->name = (void *) NGX_CONF_UNSET;
1133 
1134 #if (NGX_DEBUG)
1135 
1136     if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
1137                        sizeof(ngx_event_debug_t)) == NGX_ERROR)
1138     {
1139         return NULL;
1140     }
1141 
1142 #endif
1143 
1144     return ecf;
1145 }
1146 
1147 
1148 static char *
1149 ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
1150 {
1151     ngx_event_conf_t  *ecf = conf;
1152 
1153 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
1154     int                  fd;
1155 #endif
1156 #if (NGX_HAVE_RTSIG)
1157     ngx_uint_t           rtsig;
1158     ngx_core_conf_t     *ccf;
1159 #endif
1160     ngx_int_t            i;
1161     ngx_module_t        *module;
1162     ngx_event_module_t  *event_module;
1163 
1164     module = NULL;
1165 
1166 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
1167 
1168     fd = epoll_create(100);
1169 
1170     if (fd != -1) {
1171         close(fd);
1172         module = &ngx_epoll_module;
1173 
1174     } else if (ngx_errno != NGX_ENOSYS) {
1175         module = &ngx_epoll_module;
1176     }
1177 
1178 #endif
1179 
1180 #if (NGX_HAVE_RTSIG)
1181 
1182     if (module == NULL) {
1183         module = &ngx_rtsig_module;
1184         rtsig = 1;
1185 
1186     } else {
1187         rtsig = 0;
1188     }
1189 
1190 #endif
1191 
1192 #if (NGX_HAVE_DEVPOLL)
1193 
1194     module = &ngx_devpoll_module;
1195 
1196 #endif
1197 
1198 #if (NGX_HAVE_KQUEUE)
1199 
1200     module = &ngx_kqueue_module;
1201 
1202 #endif
1203 
1204 #if (NGX_HAVE_SELECT)
1205 
1206     if (module == NULL) {
1207         module = &ngx_select_module;
1208     }
1209 
1210 #endif
1211 
1212     if (module == NULL) {
1213         for (i = 0; ngx_modules[i]; i++) {
1214 
1215             if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
1216                 continue;
1217             }
1218 
1219             event_module = ngx_modules[i]->ctx;
1220 
1221             if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
1222             {
1223                 continue;
1224             }
1225 
1226             module = ngx_modules[i];
1227             break;
1228         }
1229     }
1230 
1231     if (module == NULL) {
1232         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
1233         return NGX_CONF_ERROR;
1234     }
1235 
1236     ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);
1237     cycle->connection_n = ecf->connections;
1238 
1239     ngx_conf_init_uint_value(ecf->use, module->ctx_index);
1240 
1241     event_module = module->ctx;
1242     ngx_conf_init_ptr_value(ecf->name, event_module->name->data);
1243 
1244     ngx_conf_init_value(ecf->multi_accept, 0);
1245     ngx_conf_init_value(ecf->accept_mutex, 1);
1246     ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
1247 
1248 
1249 #if (NGX_HAVE_RTSIG)
1250 
1251     if (!rtsig) {
1252         return NGX_CONF_OK;
1253     }
1254 
1255     if (ecf->accept_mutex) {
1256         return NGX_CONF_OK;
1257     }
1258 
1259     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
1260 
1261     if (ccf->worker_processes == 0) {
1262         return NGX_CONF_OK;
1263     }
1264 
1265     ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
1266                   "the \"rtsig\" method requires \"accept_mutex\" to be on");
1267 
1268     return NGX_CONF_ERROR;
1269 
1270 #else
1271 
1272     return NGX_CONF_OK;
1273 
1274 #endif
1275 }
1276 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.