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