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 }