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 }