Mercurial > hg > nginx-ranges
comparison src/os/unix/ngx_process_cycle.c @ 525:43cc6f0b77ce NGINX_0_8_9
nginx 0.8.9
*) Feature: now the start cache loader runs in a separate process; this
should improve large caches handling.
*) Feature: now temporarily files and permanent storage area may reside
at different file systems.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 17 Aug 2009 00:00:00 +0400 |
parents | 56baf312c1b5 |
children | 7efcdb937752 |
comparison
equal
deleted
inserted
replaced
524:16d97d9e72b7 | 525:43cc6f0b77ce |
---|---|
10 #include <ngx_channel.h> | 10 #include <ngx_channel.h> |
11 | 11 |
12 | 12 |
13 static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, | 13 static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, |
14 ngx_int_t type); | 14 ngx_int_t type); |
15 static void ngx_start_cache_manager_process(ngx_cycle_t *cycle, ngx_int_t type); | 15 static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle, |
16 ngx_uint_t respawn); | |
17 static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch); | |
16 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); | 18 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); |
17 static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle); | 19 static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle); |
18 static void ngx_master_process_exit(ngx_cycle_t *cycle); | 20 static void ngx_master_process_exit(ngx_cycle_t *cycle); |
19 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); | 21 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); |
20 static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority); | 22 static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority); |
24 static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle); | 26 static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle); |
25 static ngx_thread_value_t ngx_worker_thread_cycle(void *data); | 27 static ngx_thread_value_t ngx_worker_thread_cycle(void *data); |
26 #endif | 28 #endif |
27 static void ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data); | 29 static void ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data); |
28 static void ngx_cache_manager_process_handler(ngx_event_t *ev); | 30 static void ngx_cache_manager_process_handler(ngx_event_t *ev); |
31 static void ngx_cache_loader_process_handler(ngx_event_t *ev); | |
29 | 32 |
30 | 33 |
31 ngx_uint_t ngx_process; | 34 ngx_uint_t ngx_process; |
32 ngx_pid_t ngx_pid; | 35 ngx_pid_t ngx_pid; |
33 ngx_uint_t ngx_threaded; | 36 ngx_uint_t ngx_threaded; |
57 #endif | 60 #endif |
58 | 61 |
59 | 62 |
60 u_long cpu_affinity; | 63 u_long cpu_affinity; |
61 static u_char master_process[] = "master process"; | 64 static u_char master_process[] = "master process"; |
65 | |
66 | |
67 static ngx_cache_manager_ctx_t ngx_cache_manager_ctx = { | |
68 ngx_cache_manager_process_handler, "cache manager process", 0 | |
69 }; | |
70 | |
71 static ngx_cache_manager_ctx_t ngx_cache_loader_ctx = { | |
72 ngx_cache_loader_process_handler, "cache loader process", 60000 | |
73 }; | |
62 | 74 |
63 | 75 |
64 static ngx_cycle_t ngx_exit_cycle; | 76 static ngx_cycle_t ngx_exit_cycle; |
65 static ngx_log_t ngx_exit_log; | 77 static ngx_log_t ngx_exit_log; |
66 static ngx_open_file_t ngx_exit_log_file; | 78 static ngx_open_file_t ngx_exit_log_file; |
120 | 132 |
121 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | 133 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); |
122 | 134 |
123 ngx_start_worker_processes(cycle, ccf->worker_processes, | 135 ngx_start_worker_processes(cycle, ccf->worker_processes, |
124 NGX_PROCESS_RESPAWN); | 136 NGX_PROCESS_RESPAWN); |
125 ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN); | 137 ngx_start_cache_manager_processes(cycle, 0); |
126 | 138 |
127 ngx_new_binary = 0; | 139 ngx_new_binary = 0; |
128 delay = 0; | 140 delay = 0; |
129 live = 1; | 141 live = 1; |
130 | 142 |
201 ngx_reconfigure = 0; | 213 ngx_reconfigure = 0; |
202 | 214 |
203 if (ngx_new_binary) { | 215 if (ngx_new_binary) { |
204 ngx_start_worker_processes(cycle, ccf->worker_processes, | 216 ngx_start_worker_processes(cycle, ccf->worker_processes, |
205 NGX_PROCESS_RESPAWN); | 217 NGX_PROCESS_RESPAWN); |
206 ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN); | 218 ngx_start_cache_manager_processes(cycle, 0); |
207 ngx_noaccepting = 0; | 219 ngx_noaccepting = 0; |
208 | 220 |
209 continue; | 221 continue; |
210 } | 222 } |
211 | 223 |
220 ngx_cycle = cycle; | 232 ngx_cycle = cycle; |
221 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, | 233 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, |
222 ngx_core_module); | 234 ngx_core_module); |
223 ngx_start_worker_processes(cycle, ccf->worker_processes, | 235 ngx_start_worker_processes(cycle, ccf->worker_processes, |
224 NGX_PROCESS_JUST_RESPAWN); | 236 NGX_PROCESS_JUST_RESPAWN); |
225 ngx_start_cache_manager_process(cycle, NGX_PROCESS_JUST_RESPAWN); | 237 ngx_start_cache_manager_processes(cycle, 1); |
226 live = 1; | 238 live = 1; |
227 ngx_signal_worker_processes(cycle, | 239 ngx_signal_worker_processes(cycle, |
228 ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); | 240 ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); |
229 } | 241 } |
230 | 242 |
231 if (ngx_restart) { | 243 if (ngx_restart) { |
232 ngx_restart = 0; | 244 ngx_restart = 0; |
233 ngx_start_worker_processes(cycle, ccf->worker_processes, | 245 ngx_start_worker_processes(cycle, ccf->worker_processes, |
234 NGX_PROCESS_RESPAWN); | 246 NGX_PROCESS_RESPAWN); |
235 ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN); | 247 ngx_start_cache_manager_processes(cycle, 0); |
236 live = 1; | 248 live = 1; |
237 } | 249 } |
238 | 250 |
239 if (ngx_reopen) { | 251 if (ngx_reopen) { |
240 ngx_reopen = 0; | 252 ngx_reopen = 0; |
315 | 327 |
316 | 328 |
317 static void | 329 static void |
318 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) | 330 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) |
319 { | 331 { |
320 ngx_int_t i, s; | 332 ngx_int_t i; |
321 ngx_channel_t ch; | 333 ngx_channel_t ch; |
322 | 334 |
323 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); | 335 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); |
324 | 336 |
325 ch.command = NGX_CMD_OPEN_CHANNEL; | 337 ch.command = NGX_CMD_OPEN_CHANNEL; |
333 | 345 |
334 ch.pid = ngx_processes[ngx_process_slot].pid; | 346 ch.pid = ngx_processes[ngx_process_slot].pid; |
335 ch.slot = ngx_process_slot; | 347 ch.slot = ngx_process_slot; |
336 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | 348 ch.fd = ngx_processes[ngx_process_slot].channel[0]; |
337 | 349 |
338 for (s = 0; s < ngx_last_process; s++) { | 350 ngx_pass_open_channel(cycle, &ch); |
339 | |
340 if (s == ngx_process_slot | |
341 || ngx_processes[s].pid == -1 | |
342 || ngx_processes[s].channel[0] == -1) | |
343 { | |
344 continue; | |
345 } | |
346 | |
347 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
348 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", | |
349 ch.slot, ch.pid, ch.fd, | |
350 s, ngx_processes[s].pid, | |
351 ngx_processes[s].channel[0]); | |
352 | |
353 /* TODO: NGX_AGAIN */ | |
354 | |
355 ngx_write_channel(ngx_processes[s].channel[0], | |
356 &ch, sizeof(ngx_channel_t), cycle->log); | |
357 } | |
358 } | 351 } |
359 } | 352 } |
360 | 353 |
361 | 354 |
362 static void | 355 static void |
363 ngx_start_cache_manager_process(ngx_cycle_t *cycle, ngx_int_t type) | 356 ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) |
364 { | 357 { |
365 ngx_int_t i; | 358 ngx_uint_t i, manager, loader; |
366 ngx_uint_t n; | |
367 ngx_path_t **path; | 359 ngx_path_t **path; |
368 ngx_channel_t ch; | 360 ngx_channel_t ch; |
369 | 361 |
362 manager = 0; | |
363 loader = 0; | |
364 | |
370 path = ngx_cycle->pathes.elts; | 365 path = ngx_cycle->pathes.elts; |
371 for (n = 0; n < ngx_cycle->pathes.nelts; n++) { | 366 for (i = 0; i < ngx_cycle->pathes.nelts; i++) { |
372 if (path[n]->manager) { | 367 |
373 goto start; | 368 if (path[i]->manager) { |
374 } | 369 manager = 1; |
375 } | 370 } |
376 | 371 |
377 return; | 372 if (path[i]->loader) { |
378 | 373 loader = 1; |
379 start: | 374 } |
375 } | |
376 | |
377 if (manager == 0) { | |
378 return; | |
379 } | |
380 | |
381 ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, | |
382 &ngx_cache_manager_ctx, "cache manager process", | |
383 respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); | |
380 | 384 |
381 ch.command = NGX_CMD_OPEN_CHANNEL; | 385 ch.command = NGX_CMD_OPEN_CHANNEL; |
382 | |
383 ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, NULL, | |
384 "cache manager process", type); | |
385 | |
386 ch.pid = ngx_processes[ngx_process_slot].pid; | 386 ch.pid = ngx_processes[ngx_process_slot].pid; |
387 ch.slot = ngx_process_slot; | 387 ch.slot = ngx_process_slot; |
388 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | 388 ch.fd = ngx_processes[ngx_process_slot].channel[0]; |
389 | |
390 ngx_pass_open_channel(cycle, &ch); | |
391 | |
392 if (loader == 0) { | |
393 return; | |
394 } | |
395 | |
396 ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, | |
397 &ngx_cache_loader_ctx, "cache loader process", | |
398 respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN); | |
399 | |
400 ch.command = NGX_CMD_OPEN_CHANNEL; | |
401 ch.pid = ngx_processes[ngx_process_slot].pid; | |
402 ch.slot = ngx_process_slot; | |
403 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | |
404 | |
405 ngx_pass_open_channel(cycle, &ch); | |
406 } | |
407 | |
408 | |
409 static void | |
410 ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch) | |
411 { | |
412 ngx_int_t i; | |
389 | 413 |
390 for (i = 0; i < ngx_last_process; i++) { | 414 for (i = 0; i < ngx_last_process; i++) { |
391 | 415 |
392 if (i == ngx_process_slot | 416 if (i == ngx_process_slot |
393 || ngx_processes[i].pid == -1 | 417 || ngx_processes[i].pid == -1 |
396 continue; | 420 continue; |
397 } | 421 } |
398 | 422 |
399 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, | 423 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, |
400 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", | 424 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", |
401 ch.slot, ch.pid, ch.fd, | 425 ch->slot, ch->pid, ch->fd, |
402 i, ngx_processes[i].pid, | 426 i, ngx_processes[i].pid, |
403 ngx_processes[i].channel[0]); | 427 ngx_processes[i].channel[0]); |
404 | 428 |
405 /* TODO: NGX_AGAIN */ | 429 /* TODO: NGX_AGAIN */ |
406 | 430 |
407 ngx_write_channel(ngx_processes[i].channel[0], | 431 ngx_write_channel(ngx_processes[i].channel[0], |
408 &ch, sizeof(ngx_channel_t), cycle->log); | 432 ch, sizeof(ngx_channel_t), cycle->log); |
409 } | 433 } |
410 } | 434 } |
411 | 435 |
412 | 436 |
413 static void | 437 static void |
454 ngx_processes[i].pid, | 478 ngx_processes[i].pid, |
455 ngx_processes[i].exiting, | 479 ngx_processes[i].exiting, |
456 ngx_processes[i].exited, | 480 ngx_processes[i].exited, |
457 ngx_processes[i].detached, | 481 ngx_processes[i].detached, |
458 ngx_processes[i].respawn, | 482 ngx_processes[i].respawn, |
459 ngx_processes[i].just_respawn); | 483 ngx_processes[i].just_spawn); |
460 | 484 |
461 if (ngx_processes[i].detached || ngx_processes[i].pid == -1) { | 485 if (ngx_processes[i].detached || ngx_processes[i].pid == -1) { |
462 continue; | 486 continue; |
463 } | 487 } |
464 | 488 |
465 if (ngx_processes[i].just_respawn) { | 489 if (ngx_processes[i].just_spawn) { |
466 ngx_processes[i].just_respawn = 0; | 490 ngx_processes[i].just_spawn = 0; |
467 continue; | 491 continue; |
468 } | 492 } |
469 | 493 |
470 if (ngx_processes[i].exiting | 494 if (ngx_processes[i].exiting |
471 && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL)) | 495 && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL)) |
531 ngx_processes[i].pid, | 555 ngx_processes[i].pid, |
532 ngx_processes[i].exiting, | 556 ngx_processes[i].exiting, |
533 ngx_processes[i].exited, | 557 ngx_processes[i].exited, |
534 ngx_processes[i].detached, | 558 ngx_processes[i].detached, |
535 ngx_processes[i].respawn, | 559 ngx_processes[i].respawn, |
536 ngx_processes[i].just_respawn); | 560 ngx_processes[i].just_spawn); |
537 | 561 |
538 if (ngx_processes[i].pid == -1) { | 562 if (ngx_processes[i].pid == -1) { |
539 continue; | 563 continue; |
540 } | 564 } |
541 | 565 |
588 ch.command = NGX_CMD_OPEN_CHANNEL; | 612 ch.command = NGX_CMD_OPEN_CHANNEL; |
589 ch.pid = ngx_processes[ngx_process_slot].pid; | 613 ch.pid = ngx_processes[ngx_process_slot].pid; |
590 ch.slot = ngx_process_slot; | 614 ch.slot = ngx_process_slot; |
591 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | 615 ch.fd = ngx_processes[ngx_process_slot].channel[0]; |
592 | 616 |
593 for (n = 0; n < ngx_last_process; n++) { | 617 ngx_pass_open_channel(cycle, &ch); |
594 | |
595 if (n == ngx_process_slot | |
596 || ngx_processes[n].pid == -1 | |
597 || ngx_processes[n].channel[0] == -1) | |
598 { | |
599 continue; | |
600 } | |
601 | |
602 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
603 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", | |
604 ch.slot, ch.pid, ch.fd, | |
605 n, ngx_processes[n].pid, | |
606 ngx_processes[n].channel[0]); | |
607 | |
608 /* TODO: NGX_AGAIN */ | |
609 | |
610 ngx_write_channel(ngx_processes[n].channel[0], | |
611 &ch, sizeof(ngx_channel_t), cycle->log); | |
612 } | |
613 | 618 |
614 live = 1; | 619 live = 1; |
615 | 620 |
616 continue; | 621 continue; |
617 } | 622 } |
1010 && !c[i].read->accept | 1015 && !c[i].read->accept |
1011 && !c[i].read->channel | 1016 && !c[i].read->channel |
1012 && !c[i].read->resolver) | 1017 && !c[i].read->resolver) |
1013 { | 1018 { |
1014 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 1019 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
1015 "open socket #%d left in connection %ui%s", | 1020 "open socket #%d left in connection %ui", |
1016 c[i].fd, i, ngx_debug_quit ? ", aborting" : ""); | 1021 c[i].fd, i); |
1017 ngx_debug_point(); | 1022 ngx_debug_quit = 1; |
1018 } | 1023 } |
1019 } | 1024 } |
1020 | 1025 |
1021 if (ngx_debug_quit) { | 1026 if (ngx_debug_quit) { |
1027 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "aborting"); | |
1022 ngx_debug_point(); | 1028 ngx_debug_point(); |
1023 } | 1029 } |
1024 } | 1030 } |
1025 | 1031 |
1026 /* | 1032 /* |
1263 | 1269 |
1264 | 1270 |
1265 static void | 1271 static void |
1266 ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data) | 1272 ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data) |
1267 { | 1273 { |
1274 ngx_cache_manager_ctx_t *ctx = data; | |
1275 | |
1268 void *ident[4]; | 1276 void *ident[4]; |
1269 ngx_event_t ev; | 1277 ngx_event_t ev; |
1270 | 1278 |
1271 cycle->connection_n = 512; | 1279 cycle->connection_n = 512; |
1272 | 1280 |
1273 ngx_worker_process_init(cycle, 0); | 1281 ngx_worker_process_init(cycle, 0); |
1274 | 1282 |
1275 ngx_close_listening_sockets(cycle); | 1283 ngx_close_listening_sockets(cycle); |
1276 | 1284 |
1277 ngx_memzero(&ev, sizeof(ngx_event_t)); | 1285 ngx_memzero(&ev, sizeof(ngx_event_t)); |
1278 ev.handler = ngx_cache_manager_process_handler; | 1286 ev.handler = ctx->handler; |
1279 ev.data = ident; | 1287 ev.data = ident; |
1280 ev.log = cycle->log; | 1288 ev.log = cycle->log; |
1281 ident[3] = (void *) -1; | 1289 ident[3] = (void *) -1; |
1282 | 1290 |
1283 ngx_use_accept_mutex = 0; | 1291 ngx_use_accept_mutex = 0; |
1284 | 1292 |
1285 ngx_setproctitle("cache manager process"); | 1293 ngx_setproctitle(ctx->name); |
1286 | 1294 |
1287 ngx_add_timer(&ev, 0); | 1295 ngx_add_timer(&ev, ctx->delay); |
1288 | 1296 |
1289 for ( ;; ) { | 1297 for ( ;; ) { |
1290 | 1298 |
1291 if (ngx_terminate || ngx_quit) { | 1299 if (ngx_terminate || ngx_quit) { |
1292 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); | 1300 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); |
1329 next = 1; | 1337 next = 1; |
1330 } | 1338 } |
1331 | 1339 |
1332 ngx_add_timer(ev, next * 1000); | 1340 ngx_add_timer(ev, next * 1000); |
1333 } | 1341 } |
1342 | |
1343 | |
1344 static void | |
1345 ngx_cache_loader_process_handler(ngx_event_t *ev) | |
1346 { | |
1347 ngx_uint_t i; | |
1348 ngx_path_t **path; | |
1349 ngx_cycle_t *cycle; | |
1350 | |
1351 cycle = (ngx_cycle_t *) ngx_cycle; | |
1352 | |
1353 path = cycle->pathes.elts; | |
1354 for (i = 0; i < cycle->pathes.nelts; i++) { | |
1355 | |
1356 if (ngx_terminate || ngx_quit) { | |
1357 break; | |
1358 } | |
1359 | |
1360 if (path[i]->loader) { | |
1361 path[i]->loader(path[i]->data); | |
1362 ngx_time_update(0, 0); | |
1363 } | |
1364 } | |
1365 | |
1366 exit(0); | |
1367 } |