Mercurial > hg > nginx
comparison src/os/unix/ngx_process_cycle.c @ 3247:1f3cd08ebb82 stable-0.7
merge r3017, r3018, r3019, r3020, r3021, r3022, r3023, r3196:
cache management fixes:
*) separate cache loader process
*) use real file cache length, this fixes cache size counting for responses
without "Content-Length" header and 304 responses.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 26 Oct 2009 17:23:49 +0000 |
parents | 4b5cf483c6a8 |
children | 8c76116820f3 |
comparison
equal
deleted
inserted
replaced
3246:eb555a9a57d4 | 3247:1f3cd08ebb82 |
---|---|
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; |
58 #endif | 61 #endif |
59 | 62 |
60 | 63 |
61 u_long cpu_affinity; | 64 u_long cpu_affinity; |
62 static u_char master_process[] = "master process"; | 65 static u_char master_process[] = "master process"; |
66 | |
67 | |
68 static ngx_cache_manager_ctx_t ngx_cache_manager_ctx = { | |
69 ngx_cache_manager_process_handler, "cache manager process", 0 | |
70 }; | |
71 | |
72 static ngx_cache_manager_ctx_t ngx_cache_loader_ctx = { | |
73 ngx_cache_loader_process_handler, "cache loader process", 60000 | |
74 }; | |
63 | 75 |
64 | 76 |
65 static ngx_cycle_t ngx_exit_cycle; | 77 static ngx_cycle_t ngx_exit_cycle; |
66 static ngx_log_t ngx_exit_log; | 78 static ngx_log_t ngx_exit_log; |
67 static ngx_open_file_t ngx_exit_log_file; | 79 static ngx_open_file_t ngx_exit_log_file; |
121 | 133 |
122 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | 134 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); |
123 | 135 |
124 ngx_start_worker_processes(cycle, ccf->worker_processes, | 136 ngx_start_worker_processes(cycle, ccf->worker_processes, |
125 NGX_PROCESS_RESPAWN); | 137 NGX_PROCESS_RESPAWN); |
126 ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN); | 138 ngx_start_cache_manager_processes(cycle, 0); |
127 | 139 |
128 ngx_new_binary = 0; | 140 ngx_new_binary = 0; |
129 delay = 0; | 141 delay = 0; |
130 live = 1; | 142 live = 1; |
131 | 143 |
205 ngx_reconfigure = 0; | 217 ngx_reconfigure = 0; |
206 | 218 |
207 if (ngx_new_binary) { | 219 if (ngx_new_binary) { |
208 ngx_start_worker_processes(cycle, ccf->worker_processes, | 220 ngx_start_worker_processes(cycle, ccf->worker_processes, |
209 NGX_PROCESS_RESPAWN); | 221 NGX_PROCESS_RESPAWN); |
210 ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN); | 222 ngx_start_cache_manager_processes(cycle, 0); |
211 ngx_noaccepting = 0; | 223 ngx_noaccepting = 0; |
212 | 224 |
213 continue; | 225 continue; |
214 } | 226 } |
215 | 227 |
224 ngx_cycle = cycle; | 236 ngx_cycle = cycle; |
225 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, | 237 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, |
226 ngx_core_module); | 238 ngx_core_module); |
227 ngx_start_worker_processes(cycle, ccf->worker_processes, | 239 ngx_start_worker_processes(cycle, ccf->worker_processes, |
228 NGX_PROCESS_JUST_RESPAWN); | 240 NGX_PROCESS_JUST_RESPAWN); |
229 ngx_start_cache_manager_process(cycle, NGX_PROCESS_JUST_RESPAWN); | 241 ngx_start_cache_manager_processes(cycle, 1); |
230 live = 1; | 242 live = 1; |
231 ngx_signal_worker_processes(cycle, | 243 ngx_signal_worker_processes(cycle, |
232 ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); | 244 ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); |
233 } | 245 } |
234 | 246 |
235 if (ngx_restart) { | 247 if (ngx_restart) { |
236 ngx_restart = 0; | 248 ngx_restart = 0; |
237 ngx_start_worker_processes(cycle, ccf->worker_processes, | 249 ngx_start_worker_processes(cycle, ccf->worker_processes, |
238 NGX_PROCESS_RESPAWN); | 250 NGX_PROCESS_RESPAWN); |
239 ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN); | 251 ngx_start_cache_manager_processes(cycle, 0); |
240 live = 1; | 252 live = 1; |
241 } | 253 } |
242 | 254 |
243 if (ngx_reopen) { | 255 if (ngx_reopen) { |
244 ngx_reopen = 0; | 256 ngx_reopen = 0; |
319 | 331 |
320 | 332 |
321 static void | 333 static void |
322 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) | 334 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type) |
323 { | 335 { |
324 ngx_int_t i, s; | 336 ngx_int_t i; |
325 ngx_channel_t ch; | 337 ngx_channel_t ch; |
326 | 338 |
327 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); | 339 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); |
328 | 340 |
329 ch.command = NGX_CMD_OPEN_CHANNEL; | 341 ch.command = NGX_CMD_OPEN_CHANNEL; |
337 | 349 |
338 ch.pid = ngx_processes[ngx_process_slot].pid; | 350 ch.pid = ngx_processes[ngx_process_slot].pid; |
339 ch.slot = ngx_process_slot; | 351 ch.slot = ngx_process_slot; |
340 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | 352 ch.fd = ngx_processes[ngx_process_slot].channel[0]; |
341 | 353 |
342 for (s = 0; s < ngx_last_process; s++) { | 354 ngx_pass_open_channel(cycle, &ch); |
343 | |
344 if (s == ngx_process_slot | |
345 || ngx_processes[s].pid == -1 | |
346 || ngx_processes[s].channel[0] == -1) | |
347 { | |
348 continue; | |
349 } | |
350 | |
351 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
352 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", | |
353 ch.slot, ch.pid, ch.fd, | |
354 s, ngx_processes[s].pid, | |
355 ngx_processes[s].channel[0]); | |
356 | |
357 /* TODO: NGX_AGAIN */ | |
358 | |
359 ngx_write_channel(ngx_processes[s].channel[0], | |
360 &ch, sizeof(ngx_channel_t), cycle->log); | |
361 } | |
362 } | 355 } |
363 } | 356 } |
364 | 357 |
365 | 358 |
366 static void | 359 static void |
367 ngx_start_cache_manager_process(ngx_cycle_t *cycle, ngx_int_t type) | 360 ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn) |
368 { | 361 { |
369 ngx_int_t i; | 362 ngx_uint_t i, manager, loader; |
370 ngx_uint_t n; | |
371 ngx_path_t **path; | 363 ngx_path_t **path; |
372 ngx_channel_t ch; | 364 ngx_channel_t ch; |
373 | 365 |
366 manager = 0; | |
367 loader = 0; | |
368 | |
374 path = ngx_cycle->pathes.elts; | 369 path = ngx_cycle->pathes.elts; |
375 for (n = 0; n < ngx_cycle->pathes.nelts; n++) { | 370 for (i = 0; i < ngx_cycle->pathes.nelts; i++) { |
376 if (path[n]->manager) { | 371 |
377 goto start; | 372 if (path[i]->manager) { |
378 } | 373 manager = 1; |
379 } | 374 } |
380 | 375 |
381 return; | 376 if (path[i]->loader) { |
382 | 377 loader = 1; |
383 start: | 378 } |
379 } | |
380 | |
381 if (manager == 0) { | |
382 return; | |
383 } | |
384 | |
385 ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, | |
386 &ngx_cache_manager_ctx, "cache manager process", | |
387 respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN); | |
384 | 388 |
385 ch.command = NGX_CMD_OPEN_CHANNEL; | 389 ch.command = NGX_CMD_OPEN_CHANNEL; |
386 | |
387 ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, NULL, | |
388 "cache manager process", type); | |
389 | |
390 ch.pid = ngx_processes[ngx_process_slot].pid; | 390 ch.pid = ngx_processes[ngx_process_slot].pid; |
391 ch.slot = ngx_process_slot; | 391 ch.slot = ngx_process_slot; |
392 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | 392 ch.fd = ngx_processes[ngx_process_slot].channel[0]; |
393 | |
394 ngx_pass_open_channel(cycle, &ch); | |
395 | |
396 if (loader == 0) { | |
397 return; | |
398 } | |
399 | |
400 ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, | |
401 &ngx_cache_loader_ctx, "cache loader process", | |
402 respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN); | |
403 | |
404 ch.command = NGX_CMD_OPEN_CHANNEL; | |
405 ch.pid = ngx_processes[ngx_process_slot].pid; | |
406 ch.slot = ngx_process_slot; | |
407 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | |
408 | |
409 ngx_pass_open_channel(cycle, &ch); | |
410 } | |
411 | |
412 | |
413 static void | |
414 ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch) | |
415 { | |
416 ngx_int_t i; | |
393 | 417 |
394 for (i = 0; i < ngx_last_process; i++) { | 418 for (i = 0; i < ngx_last_process; i++) { |
395 | 419 |
396 if (i == ngx_process_slot | 420 if (i == ngx_process_slot |
397 || ngx_processes[i].pid == -1 | 421 || ngx_processes[i].pid == -1 |
400 continue; | 424 continue; |
401 } | 425 } |
402 | 426 |
403 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, | 427 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, |
404 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", | 428 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", |
405 ch.slot, ch.pid, ch.fd, | 429 ch->slot, ch->pid, ch->fd, |
406 i, ngx_processes[i].pid, | 430 i, ngx_processes[i].pid, |
407 ngx_processes[i].channel[0]); | 431 ngx_processes[i].channel[0]); |
408 | 432 |
409 /* TODO: NGX_AGAIN */ | 433 /* TODO: NGX_AGAIN */ |
410 | 434 |
411 ngx_write_channel(ngx_processes[i].channel[0], | 435 ngx_write_channel(ngx_processes[i].channel[0], |
412 &ch, sizeof(ngx_channel_t), cycle->log); | 436 ch, sizeof(ngx_channel_t), cycle->log); |
413 } | 437 } |
414 } | 438 } |
415 | 439 |
416 | 440 |
417 static void | 441 static void |
458 ngx_processes[i].pid, | 482 ngx_processes[i].pid, |
459 ngx_processes[i].exiting, | 483 ngx_processes[i].exiting, |
460 ngx_processes[i].exited, | 484 ngx_processes[i].exited, |
461 ngx_processes[i].detached, | 485 ngx_processes[i].detached, |
462 ngx_processes[i].respawn, | 486 ngx_processes[i].respawn, |
463 ngx_processes[i].just_respawn); | 487 ngx_processes[i].just_spawn); |
464 | 488 |
465 if (ngx_processes[i].detached || ngx_processes[i].pid == -1) { | 489 if (ngx_processes[i].detached || ngx_processes[i].pid == -1) { |
466 continue; | 490 continue; |
467 } | 491 } |
468 | 492 |
469 if (ngx_processes[i].just_respawn) { | 493 if (ngx_processes[i].just_spawn) { |
470 ngx_processes[i].just_respawn = 0; | 494 ngx_processes[i].just_spawn = 0; |
471 continue; | 495 continue; |
472 } | 496 } |
473 | 497 |
474 if (ngx_processes[i].exiting | 498 if (ngx_processes[i].exiting |
475 && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL)) | 499 && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL)) |
534 ngx_processes[i].pid, | 558 ngx_processes[i].pid, |
535 ngx_processes[i].exiting, | 559 ngx_processes[i].exiting, |
536 ngx_processes[i].exited, | 560 ngx_processes[i].exited, |
537 ngx_processes[i].detached, | 561 ngx_processes[i].detached, |
538 ngx_processes[i].respawn, | 562 ngx_processes[i].respawn, |
539 ngx_processes[i].just_respawn); | 563 ngx_processes[i].just_spawn); |
540 | 564 |
541 if (ngx_processes[i].pid == -1) { | 565 if (ngx_processes[i].pid == -1) { |
542 continue; | 566 continue; |
543 } | 567 } |
544 | 568 |
591 ch.command = NGX_CMD_OPEN_CHANNEL; | 615 ch.command = NGX_CMD_OPEN_CHANNEL; |
592 ch.pid = ngx_processes[ngx_process_slot].pid; | 616 ch.pid = ngx_processes[ngx_process_slot].pid; |
593 ch.slot = ngx_process_slot; | 617 ch.slot = ngx_process_slot; |
594 ch.fd = ngx_processes[ngx_process_slot].channel[0]; | 618 ch.fd = ngx_processes[ngx_process_slot].channel[0]; |
595 | 619 |
596 for (n = 0; n < ngx_last_process; n++) { | 620 ngx_pass_open_channel(cycle, &ch); |
597 | |
598 if (n == ngx_process_slot | |
599 || ngx_processes[n].pid == -1 | |
600 || ngx_processes[n].channel[0] == -1) | |
601 { | |
602 continue; | |
603 } | |
604 | |
605 ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
606 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", | |
607 ch.slot, ch.pid, ch.fd, | |
608 n, ngx_processes[n].pid, | |
609 ngx_processes[n].channel[0]); | |
610 | |
611 /* TODO: NGX_AGAIN */ | |
612 | |
613 ngx_write_channel(ngx_processes[n].channel[0], | |
614 &ch, sizeof(ngx_channel_t), cycle->log); | |
615 } | |
616 | 621 |
617 live = 1; | 622 live = 1; |
618 | 623 |
619 continue; | 624 continue; |
620 } | 625 } |
1266 | 1271 |
1267 | 1272 |
1268 static void | 1273 static void |
1269 ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data) | 1274 ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data) |
1270 { | 1275 { |
1276 ngx_cache_manager_ctx_t *ctx = data; | |
1277 | |
1271 void *ident[4]; | 1278 void *ident[4]; |
1272 ngx_event_t ev; | 1279 ngx_event_t ev; |
1273 | 1280 |
1274 cycle->connection_n = 512; | 1281 cycle->connection_n = 512; |
1275 | 1282 |
1276 ngx_worker_process_init(cycle, 0); | 1283 ngx_worker_process_init(cycle, 0); |
1277 | 1284 |
1278 ngx_close_listening_sockets(cycle); | 1285 ngx_close_listening_sockets(cycle); |
1279 | 1286 |
1280 ngx_memzero(&ev, sizeof(ngx_event_t)); | 1287 ngx_memzero(&ev, sizeof(ngx_event_t)); |
1281 ev.handler = ngx_cache_manager_process_handler; | 1288 ev.handler = ctx->handler; |
1282 ev.data = ident; | 1289 ev.data = ident; |
1283 ev.log = cycle->log; | 1290 ev.log = cycle->log; |
1284 ident[3] = (void *) -1; | 1291 ident[3] = (void *) -1; |
1285 | 1292 |
1286 ngx_use_accept_mutex = 0; | 1293 ngx_use_accept_mutex = 0; |
1287 | 1294 |
1288 ngx_setproctitle("cache manager process"); | 1295 ngx_setproctitle(ctx->name); |
1289 | 1296 |
1290 ngx_add_timer(&ev, 0); | 1297 ngx_add_timer(&ev, ctx->delay); |
1291 | 1298 |
1292 for ( ;; ) { | 1299 for ( ;; ) { |
1293 | 1300 |
1294 if (ngx_terminate || ngx_quit) { | 1301 if (ngx_terminate || ngx_quit) { |
1295 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); | 1302 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); |
1332 next = 1; | 1339 next = 1; |
1333 } | 1340 } |
1334 | 1341 |
1335 ngx_add_timer(ev, next * 1000); | 1342 ngx_add_timer(ev, next * 1000); |
1336 } | 1343 } |
1344 | |
1345 | |
1346 static void | |
1347 ngx_cache_loader_process_handler(ngx_event_t *ev) | |
1348 { | |
1349 ngx_uint_t i; | |
1350 ngx_path_t **path; | |
1351 ngx_cycle_t *cycle; | |
1352 | |
1353 cycle = (ngx_cycle_t *) ngx_cycle; | |
1354 | |
1355 path = cycle->pathes.elts; | |
1356 for (i = 0; i < cycle->pathes.nelts; i++) { | |
1357 | |
1358 if (ngx_terminate || ngx_quit) { | |
1359 break; | |
1360 } | |
1361 | |
1362 if (path[i]->loader) { | |
1363 path[i]->loader(path[i]->data); | |
1364 ngx_time_update(0, 0); | |
1365 } | |
1366 } | |
1367 | |
1368 exit(0); | |
1369 } |