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 }