diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-11-20 19:52:20 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-11-20 19:52:20 +0000 |
commit | d43bee8ee939992404d59ae0fec248ce46abecb0 (patch) | |
tree | 6eb79a6902f147bedb8c85350cbdc68543115907 /src/os/unix/ngx_process_cycle.c | |
parent | 13376e1538e2b29e436805c626f6837b34a482c5 (diff) | |
download | nginx-d43bee8ee939992404d59ae0fec248ce46abecb0.tar.gz nginx-d43bee8ee939992404d59ae0fec248ce46abecb0.zip |
nginx-0.1.8-RELEASE importrelease-0.1.8
*) Bugfix: in the ngx_http_autoindex_module if the long file names were
in the listing.
*) Feature: the "^~" modifier in the location directive.
*) Feature: the proxy_max_temp_file_size directive.
Diffstat (limited to 'src/os/unix/ngx_process_cycle.c')
-rw-r--r-- | src/os/unix/ngx_process_cycle.c | 323 |
1 files changed, 214 insertions, 109 deletions
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 0447bc4ec..37b2ef193 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -12,15 +12,18 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type); +static void ngx_start_garbage_collector(ngx_cycle_t *cycle, ngx_int_t type); static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle); static void ngx_master_exit(ngx_cycle_t *cycle); static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); +static void ngx_worker_process_init(ngx_cycle_t *cycle); static void ngx_channel_handler(ngx_event_t *ev); #if (NGX_THREADS) static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle); static void *ngx_worker_thread_cycle(void *data); #endif +static void ngx_garbage_collector_cycle(ngx_cycle_t *cycle, void *data); ngx_uint_t ngx_process; @@ -109,6 +112,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN); + ngx_start_garbage_collector(cycle, NGX_PROCESS_RESPAWN); ngx_new_binary = 0; delay = 0; @@ -179,6 +183,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) if (!ngx_noaccepting) { ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_JUST_RESPAWN); + ngx_start_garbage_collector(cycle, NGX_PROCESS_JUST_RESPAWN); live = 1; ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); @@ -193,6 +198,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN); + ngx_start_garbage_collector(cycle, NGX_PROCESS_RESPAWN); ngx_noaccepting = 0; continue; @@ -211,6 +217,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) ngx_core_module); ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_JUST_RESPAWN); + ngx_start_garbage_collector(cycle, NGX_PROCESS_JUST_RESPAWN); live = 1; ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); @@ -220,6 +227,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) ngx_restart = 0; ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN); + ngx_start_garbage_collector(cycle, NGX_PROCESS_RESPAWN); live = 1; } @@ -352,6 +360,47 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, } +static void ngx_start_garbage_collector(ngx_cycle_t *cycle, ngx_int_t type) +{ + ngx_int_t i; + ngx_channel_t ch; + + return; + + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "start garbage collector"); + + ch.command = NGX_CMD_OPEN_CHANNEL; + + ngx_spawn_process(cycle, ngx_garbage_collector_cycle, NULL, + "garbage collector", type); + + ch.pid = ngx_processes[ngx_process_slot].pid; + ch.slot = ngx_process_slot; + ch.fd = ngx_processes[ngx_process_slot].channel[0]; + + for (i = 0; i < ngx_last_process; i++) { + + if (i == ngx_process_slot + || ngx_processes[i].pid == -1 + || ngx_processes[i].channel[0] == -1) + { + continue; + } + + ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, + "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", + ch.slot, ch.pid, ch.fd, + i, ngx_processes[i].pid, + ngx_processes[i].channel[0]); + + /* TODO: NGX_AGAIN */ + + ngx_write_channel(ngx_processes[i].channel[0], + &ch, sizeof(ngx_channel_t), cycle->log); + } +} + + static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo) { ngx_int_t i; @@ -558,15 +607,119 @@ static void ngx_master_exit(ngx_cycle_t *cycle) static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { + ngx_worker_process_init(cycle); + + ngx_setproctitle("worker process"); + +#if (NGX_THREADS) + + if (ngx_time_mutex_init(cycle->log) == NGX_ERROR) { + /* fatal */ + exit(2); + } + + if (ngx_threads_n) { + if (ngx_init_threads(ngx_threads_n, + ccf->thread_stack_size, cycle) == NGX_ERROR) + { + /* fatal */ + exit(2); + } + + err = ngx_thread_key_create(&ngx_core_tls_key); + if (err != 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, err, + ngx_thread_key_create_n " failed"); + /* fatal */ + exit(2); + } + + for (n = 0; n < ngx_threads_n; n++) { + + if (!(ngx_threads[n].cv = ngx_cond_init(cycle->log))) { + /* fatal */ + exit(2); + } + + if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid, + ngx_worker_thread_cycle, + (void *) &ngx_threads[n], cycle->log) != 0) + { + /* fatal */ + exit(2); + } + } + } + +#endif + + for ( ;; ) { + if (ngx_exiting + && ngx_event_timer_rbtree == &ngx_event_timer_sentinel) + { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + + +#if (NGX_THREADS) + ngx_terminate = 1; + + ngx_wakeup_worker_threads(cycle); +#endif + + /* + * we do not destroy cycle->pool here because a signal handler + * that uses cycle->log can be called at this point + */ + exit(0); + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); + + ngx_process_events(cycle); + + if (ngx_terminate) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + +#if (NGX_THREADS) + ngx_wakeup_worker_threads(cycle); +#endif + + /* + * we do not destroy cycle->pool here because a signal handler + * that uses cycle->log can be called at this point + */ + exit(0); + } + + if (ngx_quit) { + ngx_quit = 0; + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, + "gracefully shutting down"); + ngx_setproctitle("worker process is shutting down"); + + if (!ngx_exiting) { + ngx_close_listening_sockets(cycle); + ngx_exiting = 1; + } + } + + if (ngx_reopen) { + ngx_reopen = 0; + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs"); + ngx_reopen_files(cycle, -1); + } + } +} + + +static void ngx_worker_process_init(ngx_cycle_t *cycle) +{ sigset_t set; - ngx_err_t err; ngx_int_t n; ngx_uint_t i; struct timeval tv; - ngx_listening_t *ls; ngx_core_conf_t *ccf; - ngx_connection_t *c; - + ngx_listening_t *ls; ngx_gettimeofday(&tv); @@ -649,13 +802,13 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) if (close(ngx_processes[n].channel[1]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close() failed"); + "close() channel failed"); } } if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "close() failed"); + "close() channel failed"); } #if 0 @@ -668,107 +821,6 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) /* fatal */ exit(2); } - - ngx_setproctitle("worker process"); - -#if (NGX_THREADS) - - if (ngx_time_mutex_init(cycle->log) == NGX_ERROR) { - /* fatal */ - exit(2); - } - - if (ngx_threads_n) { - if (ngx_init_threads(ngx_threads_n, - ccf->thread_stack_size, cycle) == NGX_ERROR) - { - /* fatal */ - exit(2); - } - - err = ngx_thread_key_create(&ngx_core_tls_key); - if (err != 0) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - ngx_thread_key_create_n " failed"); - /* fatal */ - exit(2); - } - - for (n = 0; n < ngx_threads_n; n++) { - - if (!(ngx_threads[n].cv = ngx_cond_init(cycle->log))) { - /* fatal */ - exit(2); - } - - if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid, - ngx_worker_thread_cycle, - (void *) &ngx_threads[n], cycle->log) != 0) - { - /* fatal */ - exit(2); - } - } - } - -#endif - - for ( ;; ) { - if (ngx_exiting - && ngx_event_timer_rbtree == &ngx_event_timer_sentinel) - { - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); - - -#if (NGX_THREADS) - ngx_terminate = 1; - - ngx_wakeup_worker_threads(cycle); -#endif - - /* - * we do not destroy cycle->pool here because a signal handler - * that uses cycle->log can be called at this point - */ - exit(0); - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); - - ngx_process_events(cycle); - - if (ngx_terminate) { - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); - -#if (NGX_THREADS) - ngx_wakeup_worker_threads(cycle); -#endif - - /* - * we do not destroy cycle->pool here because a signal handler - * that uses cycle->log can be called at this point - */ - exit(0); - } - - if (ngx_quit) { - ngx_quit = 0; - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, - "gracefully shutting down"); - ngx_setproctitle("worker process is shutting down"); - - if (!ngx_exiting) { - ngx_close_listening_sockets(cycle); - ngx_exiting = 1; - } - } - - if (ngx_reopen) { - ngx_reopen = 0; - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs"); - ngx_reopen_files(cycle, -1); - } - } } @@ -778,6 +830,11 @@ static void ngx_channel_handler(ngx_event_t *ev) ngx_channel_t ch; ngx_connection_t *c; + if (ev->timedout) { + ev->timedout = 0; + return; + } + c = ev->data; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler"); @@ -834,7 +891,8 @@ static void ngx_channel_handler(ngx_event_t *ev) ngx_processes[ch.slot].channel[0]); if (close(ngx_processes[ch.slot].channel[0]) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "close() failed"); + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, + "close() channel failed"); } ngx_processes[ch.slot].channel[0] = -1; @@ -896,7 +954,6 @@ static void *ngx_worker_thread_cycle(void *data) ngx_err_t err; ngx_core_tls_t *tls; ngx_cycle_t *cycle; - struct timeval tv; thr->cv->tid = ngx_thread_self(); @@ -972,3 +1029,51 @@ static void *ngx_worker_thread_cycle(void *data) } #endif + + +static void ngx_garbage_collector_cycle(ngx_cycle_t *cycle, void *data) +{ + ngx_uint_t i; + ngx_gc_t ctx; + ngx_path_t **path; + ngx_event_t *ev; + + ngx_worker_process_init(cycle); + + ev = &cycle->read_events[ngx_channel]; + + ngx_accept_mutex = NULL; + + ngx_setproctitle("garbage collector"); + +#if 0 + ngx_add_timer(ev, 60 * 1000); +#endif + + for ( ;; ) { + + if (ngx_terminate || ngx_quit) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + exit(0); + } + + if (ngx_reopen) { + ngx_reopen = 0; + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs"); + ngx_reopen_files(cycle, -1); + } + + path = cycle->pathes.elts; + for (i = 0; i < cycle->pathes.nelts; i++) { + ctx.path = path[i]; + ctx.log = cycle->log; + ctx.handler = path[i]->gc_handler; + + ngx_collect_garbage(&ctx, &path[i]->name, 0); + } + + ngx_add_timer(ev, 60 * 60 * 1000); + + ngx_process_events(cycle); + } +} |