Mercurial > hg > nginx
comparison src/os/unix/ngx_process_cycle.c @ 354:eaf1f651cf86
nginx-0.0.7-2004-06-15-11:55:11 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 15 Jun 2004 07:55:11 +0000 |
parents | fade4edd61f8 |
children | 0fb6c53fb135 |
comparison
equal
deleted
inserted
replaced
353:b8d3d7dbfcc8 | 354:eaf1f651cf86 |
---|---|
9 static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, | 9 static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, |
10 ngx_int_t type); | 10 ngx_int_t type); |
11 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); | 11 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); |
12 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); | 12 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); |
13 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); | 13 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); |
14 static void ngx_channel_handler(ngx_event_t *ev); | |
14 #if (NGX_THREADS) | 15 #if (NGX_THREADS) |
15 static int ngx_worker_thread_cycle(void *data); | 16 static int ngx_worker_thread_cycle(void *data); |
16 #endif | 17 #endif |
17 | 18 |
18 | 19 |
20 ngx_pid_t ngx_pid; | 21 ngx_pid_t ngx_pid; |
21 ngx_uint_t ngx_threaded; | 22 ngx_uint_t ngx_threaded; |
22 | 23 |
23 sig_atomic_t ngx_reap; | 24 sig_atomic_t ngx_reap; |
24 sig_atomic_t ngx_timer; | 25 sig_atomic_t ngx_timer; |
26 sig_atomic_t ngx_sigio; | |
25 sig_atomic_t ngx_terminate; | 27 sig_atomic_t ngx_terminate; |
26 sig_atomic_t ngx_quit; | 28 sig_atomic_t ngx_quit; |
27 ngx_uint_t ngx_exiting; | 29 ngx_uint_t ngx_exiting; |
28 sig_atomic_t ngx_reconfigure; | 30 sig_atomic_t ngx_reconfigure; |
29 sig_atomic_t ngx_reopen; | 31 sig_atomic_t ngx_reopen; |
43 void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) | 45 void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) |
44 { | 46 { |
45 char *title; | 47 char *title; |
46 u_char *p; | 48 u_char *p; |
47 size_t size; | 49 size_t size; |
48 ngx_int_t n; | 50 ngx_int_t n, i; |
49 ngx_uint_t i; | |
50 sigset_t set; | 51 sigset_t set; |
51 struct timeval tv; | 52 struct timeval tv; |
52 struct itimerval itv; | 53 struct itimerval itv; |
53 ngx_uint_t live; | 54 ngx_uint_t live; |
54 ngx_msec_t delay; | 55 ngx_msec_t delay; |
55 ngx_core_conf_t *ccf; | 56 ngx_core_conf_t *ccf; |
56 | 57 |
57 sigemptyset(&set); | 58 sigemptyset(&set); |
58 sigaddset(&set, SIGCHLD); | 59 sigaddset(&set, SIGCHLD); |
59 sigaddset(&set, SIGALRM); | 60 sigaddset(&set, SIGALRM); |
61 sigaddset(&set, SIGIO); | |
60 sigaddset(&set, SIGINT); | 62 sigaddset(&set, SIGINT); |
61 sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); | 63 sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); |
62 sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); | 64 sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); |
63 sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL)); | 65 sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL)); |
64 sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL)); | 66 sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL)); |
358 } | 360 } |
359 } | 361 } |
360 | 362 |
361 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo) | 363 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo) |
362 { | 364 { |
363 ngx_uint_t i; | 365 ngx_int_t i; |
364 ngx_err_t err; | 366 ngx_err_t err; |
367 ngx_channel_t ch; | |
368 | |
369 | |
370 switch (signo) { | |
371 | |
372 case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): | |
373 ch.command = NGX_CMD_QUIT; | |
374 break; | |
375 | |
376 case ngx_signal_value(NGX_TERMINATE_SIGNAL): | |
377 ch.command = NGX_CMD_TERMINATE; | |
378 break; | |
379 | |
380 case ngx_signal_value(NGX_REOPEN_SIGNAL): | |
381 ch.command = NGX_CMD_REOPEN; | |
382 break; | |
383 | |
384 default: | |
385 ch.command = 0; | |
386 } | |
387 | |
388 ch.fd = -1; | |
389 | |
365 | 390 |
366 for (i = 0; i < ngx_last_process; i++) { | 391 for (i = 0; i < ngx_last_process; i++) { |
367 | 392 |
368 if (ngx_processes[i].detached) { | 393 if (ngx_processes[i].detached) { |
369 continue; | 394 continue; |
376 | 401 |
377 if (ngx_processes[i].exiting | 402 if (ngx_processes[i].exiting |
378 && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL)) | 403 && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL)) |
379 { | 404 { |
380 continue; | 405 continue; |
406 } | |
407 | |
408 if (ch.command) { | |
409 if (ngx_write_channel(ngx_processes[i].channel[0], | |
410 &ch, sizeof(ngx_channel_t), cycle->log) == NGX_OK) | |
411 { | |
412 if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) { | |
413 ngx_processes[i].exiting = 1; | |
414 } | |
415 | |
416 continue; | |
417 } | |
381 } | 418 } |
382 | 419 |
383 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, | 420 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, |
384 "kill (" PID_T_FMT ", %d)" , | 421 "kill (" PID_T_FMT ", %d)" , |
385 ngx_processes[i].pid, signo); | 422 ngx_processes[i].pid, signo); |
418 } | 455 } |
419 | 456 |
420 | 457 |
421 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) | 458 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) |
422 { | 459 { |
423 sigset_t set; | 460 sigset_t set; |
424 ngx_uint_t i; | 461 ngx_int_t n; |
425 ngx_listening_t *ls; | 462 ngx_uint_t i; |
426 ngx_core_conf_t *ccf; | 463 ngx_listening_t *ls; |
464 ngx_core_conf_t *ccf; | |
465 ngx_connection_t *c; | |
427 #if (NGX_THREADS) | 466 #if (NGX_THREADS) |
428 ngx_tid_t tid; | 467 ngx_tid_t tid; |
429 #endif | 468 #endif |
430 | 469 |
431 ngx_process = NGX_PROCESS_WORKER; | 470 ngx_process = NGX_PROCESS_WORKER; |
432 ngx_last_process = 0; | |
433 | 471 |
434 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | 472 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); |
435 | 473 |
436 if (ccf->group != (gid_t) NGX_CONF_UNSET) { | 474 if (ccf->group != (gid_t) NGX_CONF_UNSET) { |
437 if (setuid(ccf->group) == -1) { | 475 if (setgid(ccf->group) == -1) { |
438 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | 476 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, |
439 "setgid(%d) failed", ccf->group); | 477 "setgid(%d) failed", ccf->group); |
440 /* fatal */ | 478 /* fatal */ |
441 exit(2); | 479 exit(2); |
442 } | 480 } |
443 } | 481 } |
444 | 482 |
445 if (ccf->user != (uid_t) NGX_CONF_UNSET && geteuid() == 0) { | 483 if (ccf->user != (uid_t) NGX_CONF_UNSET) { |
446 if (setuid(ccf->user) == -1) { | 484 if (setuid(ccf->user) == -1) { |
447 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | 485 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, |
448 "setuid(%d) failed", ccf->user); | 486 "setuid(%d) failed", ccf->user); |
449 /* fatal */ | 487 /* fatal */ |
450 exit(2); | 488 exit(2); |
484 if (ngx_modules[i]->init_process) { | 522 if (ngx_modules[i]->init_process) { |
485 if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { | 523 if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { |
486 /* fatal */ | 524 /* fatal */ |
487 exit(2); | 525 exit(2); |
488 } | 526 } |
527 } | |
528 } | |
529 | |
530 for (n = 0; n < ngx_last_process; n++) { | |
531 | |
532 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
533 "close channel %d", ngx_processes[n].channel[1]); | |
534 | |
535 if (close(ngx_processes[n].channel[1]) == -1) { | |
536 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
537 "close() failed"); | |
538 } | |
539 } | |
540 | |
541 if (close(ngx_processes[ngx_last_process].channel[0]) == -1) { | |
542 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
543 "close() failed"); | |
544 } | |
545 | |
546 #if 0 | |
547 ngx_last_process = 0; | |
548 #endif | |
549 | |
550 c = &cycle->connections[ngx_channel]; | |
551 ngx_memzero(c, sizeof(ngx_connection_t)); | |
552 | |
553 c->fd = ngx_channel; | |
554 c->pool = cycle->pool; | |
555 c->read = &cycle->read_events[ngx_channel]; | |
556 c->write = &cycle->write_events[ngx_channel]; | |
557 | |
558 ngx_memzero(c->read, sizeof(ngx_event_t)); | |
559 ngx_memzero(c->write, sizeof(ngx_event_t)); | |
560 | |
561 c->log = cycle->log; | |
562 c->read->log = cycle->log; | |
563 c->write->log = cycle->log; | |
564 c->read->index = NGX_INVALID_INDEX; | |
565 c->write->index = NGX_INVALID_INDEX; | |
566 c->read->data = c; | |
567 c->write->data = c; | |
568 c->read->event_handler = ngx_channel_handler; | |
569 | |
570 if (ngx_add_conn) { | |
571 if (ngx_add_conn(c) == NGX_ERROR) { | |
572 /* fatal */ | |
573 exit(2); | |
574 } | |
575 | |
576 } else { | |
577 if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) { | |
578 /* fatal */ | |
579 exit(2); | |
489 } | 580 } |
490 } | 581 } |
491 | 582 |
492 ngx_setproctitle("worker process"); | 583 ngx_setproctitle("worker process"); |
493 | 584 |
553 } | 644 } |
554 } | 645 } |
555 } | 646 } |
556 | 647 |
557 | 648 |
649 static void ngx_channel_handler(ngx_event_t *ev) | |
650 { | |
651 ngx_int_t n; | |
652 ngx_channel_t ch; | |
653 ngx_connection_t *c; | |
654 | |
655 c = ev->data; | |
656 | |
657 n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log); | |
658 | |
659 if (n <= 0) { | |
660 return; | |
661 } | |
662 | |
663 switch (ch.command) { | |
664 | |
665 case NGX_CMD_QUIT: | |
666 ngx_quit = 1; | |
667 break; | |
668 | |
669 case NGX_CMD_TERMINATE: | |
670 ngx_terminate = 1; | |
671 break; | |
672 | |
673 case NGX_CMD_REOPEN: | |
674 ngx_reopen = 1; | |
675 break; | |
676 } | |
677 } | |
678 | |
679 | |
558 #if (NGX_THREADS) | 680 #if (NGX_THREADS) |
559 | 681 |
560 int ngx_worker_thread_cycle(void *data) | 682 int ngx_worker_thread_cycle(void *data) |
561 { | 683 { |
562 ngx_cycle_t *cycle = data; | 684 ngx_cycle_t *cycle = data; |
595 | 717 |
596 return 1; | 718 return 1; |
597 } | 719 } |
598 | 720 |
599 #endif | 721 #endif |
722 | |
723 | |
724 ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, | |
725 ngx_log_t *log) | |
726 { | |
727 ssize_t n; | |
728 ngx_err_t err; | |
729 struct iovec iov[1]; | |
730 struct msghdr msg; | |
731 struct cmsghdr cm; | |
732 | |
733 #if (HAVE_MSGHDR_MSG_CONTROL) | |
734 | |
735 if (ch->fd == -1) { | |
736 msg.msg_control = NULL; | |
737 msg.msg_controllen = 0; | |
738 | |
739 } else { | |
740 msg.msg_control = &cm; | |
741 msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int); | |
742 | |
743 cm.cmsg_len = sizeof(struct cmsghdr) + sizeof(int); | |
744 cm.cmsg_level = SOL_SOCKET; | |
745 cm.cmsg_type = SCM_RIGHTS; | |
746 *((int *) ((char *) &cm + sizeof(struct cmsghdr))) = ch->fd; | |
747 } | |
748 | |
749 #else | |
750 | |
751 if (ch->fd == -1) { | |
752 msg.msg_accrights = NULL; | |
753 msg.msg_accrightslen = 0; | |
754 | |
755 } else { | |
756 msg.msg_accrights = (caddr_t) &ch->fd; | |
757 msg.msg_accrightslen = sizeof(int); | |
758 } | |
759 | |
760 #endif | |
761 | |
762 iov[0].iov_base = (char *) ch; | |
763 iov[0].iov_len = size; | |
764 | |
765 msg.msg_name = NULL; | |
766 msg.msg_namelen = 0; | |
767 msg.msg_iov = iov; | |
768 msg.msg_iovlen = 1; | |
769 | |
770 n = sendmsg(s, &msg, MSG_DONTWAIT); | |
771 | |
772 if (n == -1) { | |
773 err = ngx_errno; | |
774 if (err == NGX_EAGAIN) { | |
775 return NGX_AGAIN; | |
776 } | |
777 | |
778 ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed"); | |
779 return NGX_ERROR; | |
780 } | |
781 | |
782 return NGX_OK; | |
783 } | |
784 | |
785 | |
786 ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, | |
787 ngx_log_t *log) | |
788 { | |
789 int fd; | |
790 ssize_t n; | |
791 ngx_err_t err; | |
792 struct iovec iov[1]; | |
793 struct msghdr msg; | |
794 struct cmsghdr *cm; | |
795 | |
796 iov[0].iov_base = (char *) ch; | |
797 iov[0].iov_len = size; | |
798 | |
799 msg.msg_name = NULL; | |
800 msg.msg_namelen = 0; | |
801 msg.msg_iov = iov; | |
802 msg.msg_iovlen = 1; | |
803 | |
804 #if (HAVE_MSGHDR_MSG_CONTROL) | |
805 msg.msg_control = &cm; | |
806 msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int); | |
807 #else | |
808 msg.msg_accrights = (caddr_t) &fd; | |
809 msg.msg_accrightslen = sizeof(int); | |
810 #endif | |
811 | |
812 n = recvmsg(s, &msg, MSG_DONTWAIT); | |
813 | |
814 if (n == -1) { | |
815 err = ngx_errno; | |
816 if (err == NGX_EAGAIN) { | |
817 return NGX_AGAIN; | |
818 } | |
819 | |
820 ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed"); | |
821 return NGX_ERROR; | |
822 } | |
823 | |
824 if ((size_t) n < sizeof(ngx_channel_t)) { | |
825 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
826 "recvmsg() returned not enough data"); | |
827 return NGX_ERROR; | |
828 } | |
829 | |
830 #if (HAVE_MSGHDR_MSG_CONTROL) | |
831 | |
832 if (ch->command == NGX_CMD_OPEN_CHANNEL) { | |
833 cm = msg.msg_control; | |
834 | |
835 if (cm == NULL) { | |
836 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
837 "recvmsg() returned no ancillary data"); | |
838 return NGX_ERROR; | |
839 } | |
840 | |
841 if (cm->cmsg_len < sizeof(struct cmsghdr) + sizeof(int)) { | |
842 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
843 "recvmsg() returned too small ancillary data"); | |
844 return NGX_ERROR; | |
845 } | |
846 | |
847 if (cm->cmsg_level != SOL_SOCKET || cm->cmsg_type != SCM_RIGHTS) { | |
848 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
849 "recvmsg() returned invalid ancillary data " | |
850 "level %d or type %d", cm->cmsg_level, cm->cmsg_type); | |
851 return NGX_ERROR; | |
852 } | |
853 | |
854 ch->fd = *((int *) ((char *) cm + sizeof(struct cmsghdr))); | |
855 } | |
856 | |
857 if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { | |
858 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
859 "recvmsg() truncated data"); | |
860 } | |
861 | |
862 #else | |
863 | |
864 if (ch->command == NGX_CMD_OPEN_CHANNEL) { | |
865 if (msg.msg_accrightslen != sizeof(int)) { | |
866 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
867 "recvmsg() returned no ancillary data"); | |
868 return NGX_ERROR; | |
869 } | |
870 | |
871 ch->fd = fd; | |
872 } | |
873 | |
874 #endif | |
875 | |
876 return n; | |
877 } |