comparison src/core/nginx.c @ 279:b79f021a644a

nginx-0.0.2-2004-03-04-19:34:23 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 04 Mar 2004 16:34:23 +0000
parents 0ba4821f4460
children 30310107dbc9
comparison
equal deleted inserted replaced
278:0ba4821f4460 279:b79f021a644a
252 252
253 ngx_master_process_cycle(cycle, &ctx); 253 ngx_master_process_cycle(cycle, &ctx);
254 254
255 return 0; 255 return 0;
256 } 256 }
257
258
259 #if 0
260
261 /* TODO: broken NGX_PROCESS_SINGLE */
262
263 static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
264 {
265 int signo;
266 sigset_t set;
267 struct timeval tv;
268 struct itimerval itv;
269 ngx_uint_t i, live;
270 ngx_msec_t delay;
271 ngx_core_conf_t *ccf;
272
273 sigemptyset(&set);
274 sigaddset(&set, SIGCHLD);
275 sigaddset(&set, SIGALRM);
276 sigaddset(&set, SIGINT);
277 sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
278 sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
279 sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
280 sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
281 sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
282 sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
283
284 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
285 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
286 "sigprocmask() failed");
287 }
288
289 sigemptyset(&set);
290
291 ngx_setproctitle("master process");
292
293 ngx_new_binary = 0;
294 delay = 0;
295 signo = 0;
296 live = 0;
297
298 for ( ;; ) {
299 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "new cycle");
300
301 if (ngx_process == NGX_PROCESS_MASTER) {
302 ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
303 "worker process", NGX_PROCESS_RESPAWN);
304
305 /*
306 * we have to limit the maximum life time of the worker processes
307 * by 1 month because our millisecond event timer is limited
308 * by 49 days on 32-bit platforms
309 */
310
311 itv.it_interval.tv_sec = 0;
312 itv.it_interval.tv_usec = 0;
313 itv.it_value.tv_sec = 30 * 24 * 60 * 60;
314 itv.it_value.tv_usec = 0;
315
316 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
317 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
318 "setitimer() failed");
319 }
320
321 live = 1;
322
323 } else {
324 ngx_init_temp_number();
325
326 for (i = 0; ngx_modules[i]; i++) {
327 if (ngx_modules[i]->init_process) {
328 if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
329 /* fatal */
330 exit(1);
331 }
332 }
333 }
334 }
335
336 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
337 ngx_core_module);
338
339 /* a cycle with the same configuration because a new one is invalid */
340
341 for ( ;; ) {
342
343 /* an event loop */
344
345 for ( ;; ) {
346
347 if (ngx_process == NGX_PROCESS_MASTER) {
348 if (delay) {
349 delay *= 2;
350
351 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
352 "temination cycle: %d", delay);
353
354 itv.it_interval.tv_sec = 0;
355 itv.it_interval.tv_usec = 0;
356 itv.it_value.tv_sec = delay / 1000;
357 itv.it_value.tv_usec = (delay % 1000 ) * 1000;
358
359 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
360 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
361 "setitimer() failed");
362 }
363 }
364
365 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
366 "sigsuspend");
367
368 sigsuspend(&set);
369
370 ngx_gettimeofday(&tv);
371 ngx_time_update(tv.tv_sec);
372
373 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
374 "wake up");
375
376 } else { /* NGX_PROCESS_SINGLE */
377 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
378 "worker cycle");
379
380 ngx_process_events(cycle->log);
381 live = 0;
382 }
383
384 if (ngx_reap) {
385 ngx_reap = 0;
386 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
387 "reap childs");
388
389 live = 0;
390 for (i = 0; i < ngx_last_process; i++) {
391
392 ngx_log_debug5(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
393 "child: " PID_T_FMT
394 " e:%d t:%d d:%d r:%d",
395 ngx_processes[i].pid,
396 ngx_processes[i].exiting,
397 ngx_processes[i].exited,
398 ngx_processes[i].detached,
399 ngx_processes[i].respawn);
400
401 if (ngx_processes[i].exited) {
402
403 if (ngx_processes[i].respawn
404 && !ngx_processes[i].exiting
405 && !ngx_terminate
406 && !ngx_quit)
407 {
408 if (ngx_spawn_process(cycle,
409 ngx_processes[i].proc,
410 ngx_processes[i].data,
411 ngx_processes[i].name, i)
412 == NGX_ERROR)
413 {
414 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
415 "can not respawn %s",
416 ngx_processes[i].name);
417 continue;
418 }
419
420 live = 1;
421
422 continue;
423 }
424
425 if (ngx_processes[i].pid == ngx_new_binary) {
426 ngx_new_binary = 0;
427
428 /* TODO: if (ngx_noaccept) ngx_configure = 1 */
429 }
430
431 if (i != --ngx_last_process) {
432 ngx_processes[i--] =
433 ngx_processes[ngx_last_process];
434 }
435
436 } else if (ngx_processes[i].exiting
437 || !ngx_processes[i].detached)
438 {
439 live = 1;
440 }
441 }
442 }
443
444 if (!live && (ngx_terminate || ngx_quit)) {
445 ngx_master_exit(cycle, ctx);
446 }
447
448 if (ngx_terminate) {
449 if (delay == 0) {
450 delay = 50;
451 }
452
453 if (delay > 1000) {
454 signo = SIGKILL;
455 } else {
456 signo = ngx_signal_value(NGX_TERMINATE_SIGNAL);
457 }
458
459 } else if (ngx_quit) {
460 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
461
462 } else if (ngx_timer) {
463 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
464
465 } else {
466
467 if (ngx_noaccept) {
468 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
469 }
470
471 if (ngx_change_binary) {
472 ngx_change_binary = 0;
473 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
474 "changing binary");
475 ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv);
476 }
477
478 if (ngx_reconfigure) {
479 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
480 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
481 "reconfiguring");
482 }
483
484 if (ngx_reopen) {
485 if (ngx_process == NGX_PROCESS_MASTER) {
486 if (ccf->worker_reopen != 0) {
487 signo = ngx_signal_value(NGX_REOPEN_SIGNAL);
488 ngx_reopen = 0;
489
490 } else if (ngx_noaccept) {
491 ngx_reopen = 0;
492
493 } else {
494 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
495 }
496
497 } else { /* NGX_PROCESS_SINGLE */
498 ngx_reopen = 0;
499 }
500
501 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
502 "reopening logs");
503 ngx_reopen_files(cycle,
504 ccf->worker_reopen != 0 ? ccf->user : (uid_t) -1);
505 }
506 }
507
508 if (signo) {
509 for (i = 0; i < ngx_last_process; i++) {
510
511 if (ngx_processes[i].detached) {
512 continue;
513 }
514
515 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
516 "kill (" PID_T_FMT ", %d)" ,
517 ngx_processes[i].pid, signo);
518
519 if (kill(ngx_processes[i].pid, signo) == -1) {
520 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
521 "kill(%d, %d) failed",
522 ngx_processes[i].pid, signo);
523 continue;
524 }
525
526 if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
527 ngx_processes[i].exiting = 1;
528 }
529 }
530
531 signo = 0;
532 }
533
534 if (ngx_reopen || ngx_reconfigure || ngx_timer) {
535 break;
536 }
537 }
538
539 if (ngx_reopen) {
540 ngx_reopen = 0;
541
542 } else if (ngx_timer) {
543 ngx_timer = 0;
544
545 } else if (ngx_noaccept) {
546 ngx_noaccept = 0;
547 ngx_reconfigure = 0;
548
549 } else {
550 cycle = ngx_init_cycle(cycle);
551 if (cycle == NULL) {
552 cycle = (ngx_cycle_t *) ngx_cycle;
553 continue;
554 }
555
556 ngx_cycle = cycle;
557 ngx_reconfigure = 0;
558 }
559
560 break;
561 }
562 }
563 }
564
565
566 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
567 {
568 char *name;
569
570 if (ngx_inherited && getppid() > 1) {
571 name = ctx->pid.name.data;
572
573 } else {
574 name = ctx->name;
575 }
576
577 if (ngx_delete_file(name) == NGX_FILE_ERROR) {
578 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
579 ngx_delete_file_n " \"%s\" failed", name);
580 }
581
582 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit");
583 exit(0);
584 }
585
586
587 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
588 {
589 sigset_t set;
590 ngx_int_t i;
591 ngx_listening_t *ls;
592 ngx_core_conf_t *ccf;
593 #if (NGX_THREADS)
594 ngx_tid_t tid;
595 #endif
596
597 ngx_process = NGX_PROCESS_WORKER;
598 ngx_last_process = 0;
599
600 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
601
602 if (ccf->group != (gid_t) NGX_CONF_UNSET) {
603 if (setuid(ccf->group) == -1) {
604 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
605 "setgid(%d) failed", ccf->group);
606 /* fatal */
607 exit(2);
608 }
609 }
610
611 if (ccf->user != (uid_t) NGX_CONF_UNSET && geteuid() == 0) {
612 if (setuid(ccf->user) == -1) {
613 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
614 "setuid(%d) failed", ccf->user);
615 /* fatal */
616 exit(2);
617 }
618 }
619
620 #if (HAVE_PR_SET_DUMPABLE)
621
622 /* allow coredump after setuid() in Linux 2.4.x */
623
624 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
625 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
626 "prctl(PR_SET_DUMPABLE) failed");
627 }
628
629 #endif
630
631 sigemptyset(&set);
632
633 if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
634 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
635 "sigprocmask() failed");
636 }
637
638 ngx_init_temp_number();
639
640 /*
641 * disable deleting previous events for the listening sockets because
642 * in the worker processes there are no events at all at this point
643 */
644 ls = cycle->listening.elts;
645 for (i = 0; i < cycle->listening.nelts; i++) {
646 ls[i].remain = 0;
647 }
648
649 for (i = 0; ngx_modules[i]; i++) {
650 if (ngx_modules[i]->init_process) {
651 if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
652 /* fatal */
653 exit(1);
654 }
655 }
656 }
657
658 ngx_setproctitle("worker process");
659
660 #if (NGX_THREADS)
661
662 if (ngx_init_threads(5, 128 * 1024 * 1024, cycle) == NGX_ERROR) {
663 /* fatal */
664 exit(1);
665 }
666
667 for (i = 0; i < 1; i++) {
668 if (ngx_create_thread(&tid, ngx_worker_thread_cycle,
669 cycle, cycle->log) != 0)
670 {
671 /* fatal */
672 exit(1);
673 }
674 }
675
676 #endif
677
678 for ( ;; ) {
679 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
680
681 ngx_process_events(cycle->log);
682
683 if (ngx_terminate) {
684 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
685 exit(0);
686 }
687
688 if (ngx_quit) {
689 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
690 "gracefully shutting down");
691 ngx_setproctitle("worker process is shutting down");
692 break;
693 }
694
695 if (ngx_reopen) {
696 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
697 ngx_reopen_files(cycle, -1);
698 ngx_reopen = 0;
699 }
700 }
701
702 ngx_close_listening_sockets(cycle);
703
704 for ( ;; ) {
705 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
706 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
707 exit(0);
708 }
709
710 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
711
712 ngx_process_events(cycle->log);
713
714 if (ngx_reopen) {
715 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
716 ngx_reopen_files(cycle, -1);
717 ngx_reopen = 0;
718 }
719 }
720 }
721
722
723 #if (NGX_THREADS)
724
725 int ngx_worker_thread_cycle(void *data)
726 {
727 ngx_cycle_t *cycle = data;
728
729 struct timeval tv;
730
731 /* STUB */
732
733 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
734 "thread %d started", ngx_thread_self());
735
736 ngx_setproctitle("worker thread");
737
738 sleep(5);
739
740 ngx_gettimeofday(&tv);
741 ngx_time_update(tv.tv_sec);
742
743 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
744 "thread %d done", ngx_thread_self());
745
746 return 1;
747 }
748
749 #endif
750
751 #endif
752 257
753 258
754 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp) 259 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp)
755 { 260 {
756 char *p, *v; 261 char *p, *v;
822 327
823 env[0] = var; 328 env[0] = var;
824 env[1] = NULL; 329 env[1] = NULL;
825 ctx.envp = (char *const *) &env; 330 ctx.envp = (char *const *) &env;
826 331
827 pid = ngx_exec(cycle, &ctx); 332 pid = ngx_execute(cycle, &ctx);
828 333
829 ngx_free(var); 334 ngx_free(var);
830 335
831 return pid; 336 return pid;
832 } 337 }