support attaching to an existent Win32 shared memory
Igor Sysoev
13 years ago
8 | 8 | #include <ngx_event.h> |
9 | 9 | |
10 | 10 | |
11 | static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); | |
12 | 11 | static void ngx_destroy_cycle_pools(ngx_conf_t *conf); |
13 | 12 | static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2); |
13 | static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle, | |
14 | ngx_shm_zone_t *shm_zone); | |
15 | static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); | |
14 | 16 | static void ngx_clean_old_cycles(ngx_event_t *ev); |
15 | 17 | |
16 | 18 | |
43 | 45 | { |
44 | 46 | void *rv; |
45 | 47 | char **senv, **env; |
46 | u_char *lock_file; | |
47 | 48 | ngx_uint_t i, n; |
48 | 49 | ngx_log_t *log; |
49 | 50 | ngx_time_t *tp; |
51 | 52 | ngx_pool_t *pool; |
52 | 53 | ngx_cycle_t *cycle, **old; |
53 | 54 | ngx_shm_zone_t *shm_zone, *oshm_zone; |
54 | ngx_slab_pool_t *shpool; | |
55 | 55 | ngx_list_part_t *part, *opart; |
56 | 56 | ngx_open_file_t *file; |
57 | 57 | ngx_listening_t *ls, *nls; |
469 | 469 | goto failed; |
470 | 470 | } |
471 | 471 | |
472 | shpool = (ngx_slab_pool_t *) shm_zone[i].shm.addr; | |
473 | ||
474 | shpool->end = shm_zone[i].shm.addr + shm_zone[i].shm.size; | |
475 | shpool->min_shift = 3; | |
476 | ||
477 | #if (NGX_HAVE_ATOMIC_OPS) | |
478 | ||
479 | lock_file = NULL; | |
480 | ||
481 | #else | |
482 | ||
483 | lock_file = ngx_pnalloc(cycle->pool, | |
484 | cycle->lock_file.len + shm_zone[i].shm.name.len); | |
485 | ||
486 | if (lock_file == NULL) { | |
487 | goto failed; | |
488 | } | |
489 | ||
490 | (void) ngx_cpystrn(ngx_cpymem(lock_file, cycle->lock_file.data, | |
491 | cycle->lock_file.len), | |
492 | shm_zone[i].shm.name.data, | |
493 | shm_zone[i].shm.name.len + 1); | |
494 | ||
495 | #endif | |
496 | ||
497 | if (ngx_shmtx_create(&shpool->mutex, (void *) &shpool->lock, lock_file) | |
498 | != NGX_OK) | |
499 | { | |
500 | goto failed; | |
501 | } | |
502 | ||
503 | ngx_slab_init(shpool); | |
472 | if (!shm_zone[i].shm.exists) { | |
473 | ||
474 | if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { | |
475 | goto failed; | |
476 | } | |
477 | } | |
504 | 478 | |
505 | 479 | if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { |
506 | 480 | goto failed; |
918 | 892 | } |
919 | 893 | |
920 | 894 | |
895 | static ngx_int_t | |
896 | ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn) | |
897 | { | |
898 | u_char *file; | |
899 | ngx_slab_pool_t *sp; | |
900 | ||
901 | sp = (ngx_slab_pool_t *) zn->shm.addr; | |
902 | ||
903 | sp->end = zn->shm.addr + zn->shm.size; | |
904 | sp->min_shift = 3; | |
905 | ||
906 | #if (NGX_HAVE_ATOMIC_OPS) | |
907 | ||
908 | file = NULL; | |
909 | ||
910 | #else | |
911 | ||
912 | file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len); | |
913 | if (file == NULL) { | |
914 | return NGX_ERROR; | |
915 | } | |
916 | ||
917 | (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name); | |
918 | ||
919 | #endif | |
920 | ||
921 | if (ngx_shmtx_create(&sp->mutex, (void *) &sp->lock, file) != NGX_OK) { | |
922 | return NGX_ERROR; | |
923 | } | |
924 | ||
925 | ngx_slab_init(sp); | |
926 | ||
927 | return NGX_OK; | |
928 | } | |
929 | ||
930 | ||
921 | 931 | #if !(NGX_WIN32) |
922 | 932 | |
923 | 933 | ngx_int_t |
1215 | 1225 | shm_zone->shm.log = cf->cycle->log; |
1216 | 1226 | shm_zone->shm.size = size; |
1217 | 1227 | shm_zone->shm.name = *name; |
1228 | shm_zone->shm.exists = 0; | |
1218 | 1229 | shm_zone->init = NULL; |
1219 | 1230 | shm_zone->tag = tag; |
1220 | 1231 |
505 | 505 | #endif |
506 | 506 | |
507 | 507 | shm.size = size; |
508 | shm.name.len = sizeof("nginx_shared_zone"); | |
509 | shm.name.data = (u_char *) "nginx_shared_zone"; | |
508 | 510 | shm.log = cycle->log; |
509 | 511 | |
510 | 512 | if (ngx_shm_alloc(&shm) != NGX_OK) { |
534 | 536 | |
535 | 537 | #endif |
536 | 538 | |
537 | *ngx_connection_counter = 1; | |
539 | (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); | |
538 | 540 | |
539 | 541 | ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
540 | 542 | "counter: %p, %d", |
1420 | 1420 | return NGX_OK; |
1421 | 1421 | } |
1422 | 1422 | |
1423 | if (shm_zone->shm.exists) { | |
1424 | shm_zone->data = data; | |
1425 | return NGX_OK; | |
1426 | } | |
1427 | ||
1423 | 1428 | shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
1424 | 1429 | |
1425 | 1430 | cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); |
1427 | 1432 | return NGX_ERROR; |
1428 | 1433 | } |
1429 | 1434 | |
1435 | shpool->data = cache; | |
1436 | shm_zone->data = cache; | |
1437 | ||
1430 | 1438 | ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, |
1431 | 1439 | ngx_ssl_session_rbtree_insert_value); |
1432 | 1440 | |
1441 | 1449 | |
1442 | 1450 | ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z", |
1443 | 1451 | &shm_zone->shm.name); |
1444 | ||
1445 | shm_zone->data = cache; | |
1446 | 1452 | |
1447 | 1453 | return NGX_OK; |
1448 | 1454 | } |
9 | 9 | |
10 | 10 | |
11 | 11 | typedef struct { |
12 | u_char color; | |
13 | u_char dummy; | |
14 | u_short len; | |
15 | ngx_queue_t queue; | |
16 | ngx_msec_t last; | |
17 | ngx_uint_t excess; /* integer value, 1 corresponds to 0.001 r/s */ | |
18 | u_char data[1]; | |
12 | u_char color; | |
13 | u_char dummy; | |
14 | u_short len; | |
15 | ngx_queue_t queue; | |
16 | ngx_msec_t last; | |
17 | /* integer value, 1 corresponds to 0.001 r/s */ | |
18 | ngx_uint_t excess; | |
19 | u_char data[1]; | |
19 | 20 | } ngx_http_limit_req_node_t; |
20 | 21 | |
21 | 22 | |
22 | 23 | typedef struct { |
23 | ngx_rbtree_t *rbtree; | |
24 | ngx_queue_t *queue; | |
25 | ngx_slab_pool_t *shpool; | |
26 | ngx_uint_t rate; /* integer value, 1 corresponds to 0.001 r/s */ | |
27 | ngx_int_t index; | |
28 | ngx_str_t var; | |
24 | ngx_rbtree_t rbtree; | |
25 | ngx_rbtree_node_t sentinel; | |
26 | ngx_queue_t queue; | |
27 | } ngx_http_limit_req_shctx_t; | |
28 | ||
29 | ||
30 | typedef struct { | |
31 | ngx_http_limit_req_shctx_t *sh; | |
32 | ngx_slab_pool_t *shpool; | |
33 | /* integer value, 1 corresponds to 0.001 r/s */ | |
34 | ngx_uint_t rate; | |
35 | ngx_int_t index; | |
36 | ngx_str_t var; | |
29 | 37 | } ngx_http_limit_req_ctx_t; |
30 | 38 | |
31 | 39 | |
32 | 40 | typedef struct { |
33 | ngx_shm_zone_t *shm_zone; | |
34 | ngx_uint_t burst; /* integer value, 1 corresponds to 0.001 r/s */ | |
35 | ngx_uint_t nodelay;/* unsigned nodelay:1 */ | |
41 | ngx_shm_zone_t *shm_zone; | |
42 | /* integer value, 1 corresponds to 0.001 r/s */ | |
43 | ngx_uint_t burst; | |
44 | ngx_uint_t nodelay;/* unsigned nodelay:1 */ | |
36 | 45 | } ngx_http_limit_req_conf_t; |
37 | 46 | |
38 | 47 | |
162 | 171 | if (lr) { |
163 | 172 | ngx_queue_remove(&lr->queue); |
164 | 173 | |
165 | ngx_queue_insert_head(ctx->queue, &lr->queue); | |
174 | ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | |
166 | 175 | |
167 | 176 | excess = lr->excess; |
168 | 177 | |
238 | 247 | lr->excess = 0; |
239 | 248 | ngx_memcpy(lr->data, vv->data, len); |
240 | 249 | |
241 | ngx_rbtree_insert(ctx->rbtree, node); | |
242 | ||
243 | ngx_queue_insert_head(ctx->queue, &lr->queue); | |
250 | ngx_rbtree_insert(&ctx->sh->rbtree, node); | |
251 | ||
252 | ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | |
244 | 253 | |
245 | 254 | done: |
246 | 255 | |
323 | 332 | |
324 | 333 | ctx = lrcf->shm_zone->data; |
325 | 334 | |
326 | node = ctx->rbtree->root; | |
327 | sentinel = ctx->rbtree->sentinel; | |
335 | node = ctx->sh->rbtree.root; | |
336 | sentinel = ctx->sh->rbtree.sentinel; | |
328 | 337 | |
329 | 338 | while (node != sentinel) { |
330 | 339 | |
410 | 419 | |
411 | 420 | while (n < 3) { |
412 | 421 | |
413 | if (ngx_queue_empty(ctx->queue)) { | |
422 | if (ngx_queue_empty(&ctx->sh->queue)) { | |
414 | 423 | return; |
415 | 424 | } |
416 | 425 | |
417 | q = ngx_queue_last(ctx->queue); | |
426 | q = ngx_queue_last(&ctx->sh->queue); | |
418 | 427 | |
419 | 428 | lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); |
420 | 429 | |
439 | 448 | node = (ngx_rbtree_node_t *) |
440 | 449 | ((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); |
441 | 450 | |
442 | ngx_rbtree_delete(ctx->rbtree, node); | |
451 | ngx_rbtree_delete(&ctx->sh->rbtree, node); | |
443 | 452 | |
444 | 453 | ngx_slab_free_locked(ctx->shpool, node); |
445 | 454 | } |
452 | 461 | ngx_http_limit_req_ctx_t *octx = data; |
453 | 462 | |
454 | 463 | size_t len; |
455 | ngx_rbtree_node_t *sentinel; | |
456 | 464 | ngx_http_limit_req_ctx_t *ctx; |
457 | 465 | |
458 | 466 | ctx = shm_zone->data; |
466 | 474 | return NGX_ERROR; |
467 | 475 | } |
468 | 476 | |
469 | ctx->rbtree = octx->rbtree; | |
470 | ctx->queue = octx->queue; | |
477 | ctx->sh = octx->sh; | |
471 | 478 | ctx->shpool = octx->shpool; |
472 | 479 | |
473 | 480 | return NGX_OK; |
475 | 482 | |
476 | 483 | ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
477 | 484 | |
478 | ctx->rbtree = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_t)); | |
479 | if (ctx->rbtree == NULL) { | |
485 | if (shm_zone->shm.exists) { | |
486 | ctx->sh = ctx->shpool->data; | |
487 | ||
488 | return NGX_OK; | |
489 | } | |
490 | ||
491 | ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t)); | |
492 | if (ctx->sh == NULL) { | |
480 | 493 | return NGX_ERROR; |
481 | 494 | } |
482 | 495 | |
483 | sentinel = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_node_t)); | |
484 | if (sentinel == NULL) { | |
485 | return NGX_ERROR; | |
486 | } | |
487 | ||
488 | ngx_rbtree_init(ctx->rbtree, sentinel, | |
496 | ctx->shpool->data = ctx->sh; | |
497 | ||
498 | ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel, | |
489 | 499 | ngx_http_limit_req_rbtree_insert_value); |
490 | 500 | |
491 | ctx->queue = ngx_slab_alloc(ctx->shpool, sizeof(ngx_queue_t)); | |
492 | if (ctx->queue == NULL) { | |
493 | return NGX_ERROR; | |
494 | } | |
495 | ||
496 | ngx_queue_init(ctx->queue); | |
501 | ngx_queue_init(&ctx->sh->queue); | |
497 | 502 | |
498 | 503 | len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len; |
499 | 504 |
338 | 338 | |
339 | 339 | shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
340 | 340 | |
341 | if (shm_zone->shm.exists) { | |
342 | ctx->rbtree = shpool->data; | |
343 | ||
344 | return NGX_OK; | |
345 | } | |
346 | ||
341 | 347 | ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); |
342 | 348 | if (ctx->rbtree == NULL) { |
343 | 349 | return NGX_ERROR; |
344 | 350 | } |
351 | ||
352 | shpool->data = ctx->rbtree; | |
345 | 353 | |
346 | 354 | sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); |
347 | 355 | if (sentinel == NULL) { |
93 | 93 | } ngx_http_file_cache_header_t; |
94 | 94 | |
95 | 95 | |
96 | typedef struct { | |
97 | ngx_rbtree_t rbtree; | |
98 | ngx_rbtree_node_t sentinel; | |
99 | ngx_queue_t queue; | |
100 | ngx_atomic_t cold; | |
101 | off_t size; | |
102 | } ngx_http_file_cache_sh_t; | |
103 | ||
104 | ||
96 | 105 | struct ngx_http_file_cache_s { |
97 | ngx_rbtree_t *rbtree; | |
98 | ngx_queue_t *queue; | |
106 | ngx_http_file_cache_sh_t *sh; | |
99 | 107 | ngx_slab_pool_t *shpool; |
100 | 108 | |
101 | 109 | ngx_path_t *path; |
102 | ||
103 | ngx_atomic_t *cold; | |
104 | off_t *size; | |
105 | 110 | |
106 | 111 | off_t max_size; |
107 | 112 | size_t bsize; |
43 | 43 | ngx_http_file_cache_t *ocache = data; |
44 | 44 | |
45 | 45 | size_t len; |
46 | ngx_rbtree_node_t *sentinel; | |
47 | 46 | ngx_http_file_cache_t *cache; |
48 | 47 | |
49 | 48 | cache = shm_zone->data; |
59 | 58 | return NGX_ERROR; |
60 | 59 | } |
61 | 60 | |
62 | cache->rbtree = ocache->rbtree; | |
63 | cache->queue = ocache->queue; | |
61 | cache->sh = ocache->sh; | |
62 | ||
64 | 63 | cache->shpool = ocache->shpool; |
65 | cache->cold = ocache->cold; | |
66 | cache->size = ocache->size; | |
67 | 64 | cache->bsize = ocache->bsize; |
68 | 65 | |
69 | 66 | cache->max_size /= cache->bsize; |
73 | 70 | |
74 | 71 | cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
75 | 72 | |
76 | cache->rbtree = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_t)); | |
77 | if (cache->rbtree == NULL) { | |
73 | if (shm_zone->shm.exists) { | |
74 | cache->sh = cache->shpool->data; | |
75 | cache->bsize = ngx_fs_bsize(cache->path->name.data); | |
76 | ||
77 | return NGX_OK; | |
78 | } | |
79 | ||
80 | cache->sh = ngx_slab_alloc(cache->shpool, sizeof(ngx_http_file_cache_sh_t)); | |
81 | if (cache->sh == NULL) { | |
78 | 82 | return NGX_ERROR; |
79 | 83 | } |
80 | 84 | |
81 | sentinel = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_node_t)); | |
82 | if (sentinel == NULL) { | |
83 | return NGX_ERROR; | |
84 | } | |
85 | ||
86 | ngx_rbtree_init(cache->rbtree, sentinel, | |
85 | cache->shpool->data = cache->sh; | |
86 | ||
87 | ngx_rbtree_init(&cache->sh->rbtree, &cache->sh->sentinel, | |
87 | 88 | ngx_http_file_cache_rbtree_insert_value); |
88 | 89 | |
89 | cache->queue = ngx_slab_alloc(cache->shpool, sizeof(ngx_queue_t)); | |
90 | if (cache->queue == NULL) { | |
91 | return NGX_ERROR; | |
92 | } | |
93 | ||
94 | ngx_queue_init(cache->queue); | |
95 | ||
96 | cache->cold = ngx_slab_alloc(cache->shpool, sizeof(ngx_atomic_t)); | |
97 | if (cache->cold == NULL) { | |
98 | return NGX_ERROR; | |
99 | } | |
100 | ||
101 | *cache->cold = 1; | |
102 | ||
103 | cache->size = ngx_slab_alloc(cache->shpool, sizeof(off_t)); | |
104 | if (cache->size == NULL) { | |
105 | return NGX_ERROR; | |
106 | } | |
107 | ||
108 | *cache->size = 0; | |
90 | ngx_queue_init(&cache->sh->queue); | |
91 | ||
92 | cache->sh->cold = 1; | |
93 | cache->sh->size = 0; | |
109 | 94 | |
110 | 95 | cache->bsize = ngx_fs_bsize(cache->path->name.data); |
111 | 96 | |
201 | 186 | return rc; |
202 | 187 | } |
203 | 188 | |
204 | cold = *cache->cold; | |
189 | cold = cache->sh->cold; | |
205 | 190 | |
206 | 191 | if (rc == NGX_OK) { |
207 | 192 | |
336 | 321 | c->node->body_start = c->body_start; |
337 | 322 | c->node->exists = 1; |
338 | 323 | |
339 | *cache->size += (c->length + cache->bsize - 1) / cache->bsize; | |
324 | cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize; | |
340 | 325 | } |
341 | 326 | |
342 | 327 | ngx_shmtx_unlock(&cache->shpool->mutex); |
433 | 418 | ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], |
434 | 419 | NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); |
435 | 420 | |
436 | ngx_rbtree_insert(cache->rbtree, &fcn->node); | |
421 | ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); | |
437 | 422 | |
438 | 423 | renew: |
439 | 424 | |
453 | 438 | |
454 | 439 | fcn->expire = ngx_time() + cache->inactive; |
455 | 440 | |
456 | ngx_queue_insert_head(cache->queue, &fcn->queue); | |
441 | ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); | |
457 | 442 | |
458 | 443 | c->uniq = fcn->uniq; |
459 | 444 | c->uses = fcn->uses; |
478 | 463 | |
479 | 464 | ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t)); |
480 | 465 | |
481 | node = cache->rbtree->root; | |
482 | sentinel = cache->rbtree->sentinel; | |
466 | node = cache->sh->rbtree.root; | |
467 | sentinel = cache->sh->rbtree.sentinel; | |
483 | 468 | |
484 | 469 | while (node != sentinel) { |
485 | 470 | |
662 | 647 | |
663 | 648 | c->node->length = c->length; |
664 | 649 | |
665 | *cache->size += size; | |
650 | cache->sh->size += size; | |
666 | 651 | |
667 | 652 | if (rc == NGX_OK) { |
668 | 653 | c->node->exists = 1; |
827 | 812 | |
828 | 813 | ngx_shmtx_lock(&cache->shpool->mutex); |
829 | 814 | |
830 | for (q = ngx_queue_last(cache->queue); | |
831 | q != ngx_queue_sentinel(cache->queue); | |
815 | for (q = ngx_queue_last(&cache->sh->queue); | |
816 | q != ngx_queue_sentinel(&cache->sh->queue); | |
832 | 817 | q = ngx_queue_prev(q)) |
833 | 818 | { |
834 | 819 | fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); |
852 | 837 | if (!fcn->exists) { |
853 | 838 | |
854 | 839 | ngx_queue_remove(q); |
855 | ngx_rbtree_delete(cache->rbtree, &fcn->node); | |
840 | ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); | |
856 | 841 | ngx_slab_free_locked(cache->shpool, fcn); |
857 | 842 | |
858 | 843 | break; |
901 | 886 | |
902 | 887 | for ( ;; ) { |
903 | 888 | |
904 | if (ngx_queue_empty(cache->queue)) { | |
889 | if (ngx_queue_empty(&cache->sh->queue)) { | |
905 | 890 | wait = 10; |
906 | 891 | break; |
907 | 892 | } |
908 | 893 | |
909 | q = ngx_queue_last(cache->queue); | |
894 | q = ngx_queue_last(&cache->sh->queue); | |
910 | 895 | |
911 | 896 | fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); |
912 | 897 | |
938 | 923 | */ |
939 | 924 | |
940 | 925 | ngx_queue_remove(q); |
941 | ngx_rbtree_delete(cache->rbtree, &fcn->node); | |
926 | ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); | |
942 | 927 | |
943 | 928 | ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, |
944 | 929 | "ignore long locked inactive cache entry %*s, count:%d", |
950 | 935 | if (!fcn->exists) { |
951 | 936 | |
952 | 937 | ngx_queue_remove(q); |
953 | ngx_rbtree_delete(cache->rbtree, &fcn->node); | |
938 | ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); | |
954 | 939 | ngx_slab_free_locked(cache->shpool, fcn); |
955 | 940 | |
956 | 941 | continue; |
978 | 963 | |
979 | 964 | fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); |
980 | 965 | |
981 | *cache->size -= (fcn->length + cache->bsize - 1) / cache->bsize; | |
966 | cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize; | |
982 | 967 | |
983 | 968 | path = cache->path; |
984 | 969 | |
992 | 977 | |
993 | 978 | ngx_queue_remove(q); |
994 | 979 | |
995 | ngx_rbtree_delete(cache->rbtree, &fcn->node); | |
980 | ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); | |
996 | 981 | |
997 | 982 | ngx_slab_free_locked(cache->shpool, fcn); |
998 | 983 | |
1023 | 1008 | time_t next; |
1024 | 1009 | ngx_tree_ctx_t tree; |
1025 | 1010 | |
1026 | if (*cache->cold) { | |
1011 | if (cache->sh->cold) { | |
1027 | 1012 | |
1028 | 1013 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, |
1029 | 1014 | "http file cache manager update"); |
1044 | 1029 | return 10; |
1045 | 1030 | } |
1046 | 1031 | |
1047 | *cache->cold = 0; | |
1032 | cache->sh->cold = 0; | |
1048 | 1033 | |
1049 | 1034 | ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, |
1050 | 1035 | "http file cache: %V %.3fM, bsize: %uz", |
1051 | 1036 | &cache->path->name, |
1052 | ((double) *cache->size * cache->bsize) / (1024 * 1024), | |
1037 | ((double) cache->sh->size * cache->bsize) / (1024 * 1024), | |
1053 | 1038 | cache->bsize); |
1054 | 1039 | } |
1055 | 1040 | |
1061 | 1046 | for ( ;; ) { |
1062 | 1047 | ngx_shmtx_lock(&cache->shpool->mutex); |
1063 | 1048 | |
1064 | size = *cache->size; | |
1049 | size = cache->sh->size; | |
1065 | 1050 | |
1066 | 1051 | ngx_shmtx_unlock(&cache->shpool->mutex); |
1067 | 1052 | |
1244 | 1229 | ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], |
1245 | 1230 | NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); |
1246 | 1231 | |
1247 | ngx_rbtree_insert(cache->rbtree, &fcn->node); | |
1232 | ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); | |
1248 | 1233 | |
1249 | 1234 | fcn->uses = 1; |
1250 | 1235 | fcn->count = 0; |
1256 | 1241 | fcn->body_start = c->body_start; |
1257 | 1242 | fcn->length = c->length; |
1258 | 1243 | |
1259 | *cache->size += (c->length + cache->bsize - 1) / cache->bsize; | |
1244 | cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize; | |
1260 | 1245 | |
1261 | 1246 | } else { |
1262 | 1247 | ngx_queue_remove(&fcn->queue); |
1264 | 1249 | |
1265 | 1250 | fcn->expire = ngx_time() + cache->inactive; |
1266 | 1251 | |
1267 | ngx_queue_insert_head(cache->queue, &fcn->queue); | |
1252 | ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); | |
1268 | 1253 | |
1269 | 1254 | ngx_shmtx_unlock(&cache->shpool->mutex); |
1270 | 1255 |
12 | 12 | |
13 | 13 | |
14 | 14 | typedef struct { |
15 | u_char *addr; | |
16 | size_t size; | |
17 | ngx_str_t name; | |
18 | ngx_log_t *log; | |
15 | u_char *addr; | |
16 | size_t size; | |
17 | ngx_str_t name; | |
18 | ngx_log_t *log; | |
19 | ngx_uint_t exists; /* unsigned exists:1; */ | |
19 | 20 | } ngx_shm_t; |
20 | 21 | |
21 | 22 |
53 | 53 | extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; |
54 | 54 | extern ngx_uint_t ngx_win32_version; |
55 | 55 | extern ngx_fd_t ngx_stderr_fileno; |
56 | extern char ngx_unique[]; | |
56 | 57 | |
57 | 58 | |
58 | 59 |
10 | 10 | ngx_int_t |
11 | 11 | ngx_shm_alloc(ngx_shm_t *shm) |
12 | 12 | { |
13 | u_char *name; | |
14 | ||
15 | name = ngx_alloc(shm->name.len + 2 + sizeof(NGX_INT32_LEN), shm->log); | |
16 | if (name == NULL) { | |
17 | return NGX_ERROR; | |
18 | } | |
19 | ||
20 | ngx_sprintf(name, "%V_%s%Z", &shm->name, ngx_unique); | |
21 | ||
22 | ngx_set_errno(0); | |
23 | ||
13 | 24 | shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, |
14 | 0, shm->size, (char *) shm->name.data); | |
25 | 0, shm->size, (char *) name); | |
15 | 26 | |
16 | 27 | if (shm->handle == NULL) { |
17 | 28 | ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, |
18 | 29 | "CreateFileMapping(%uz, %s) failed", |
19 | 30 | shm->size, shm->name.data); |
20 | return NGX_ERROR; | |
31 | goto failed; | |
32 | } | |
33 | ||
34 | if (ngx_errno == ERROR_ALREADY_EXISTS) { | |
35 | shm->exists = 1; | |
21 | 36 | } |
22 | 37 | |
23 | 38 | shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); |
24 | 39 | |
25 | if (shm->addr == NULL) { | |
26 | ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, | |
27 | "MapViewOfFile(%uz) failed", shm->size); | |
28 | ||
29 | if (CloseHandle(shm->handle) == 0) { | |
30 | ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, | |
31 | "CloseHandle() failed"); | |
32 | } | |
33 | ||
34 | return NGX_ERROR; | |
40 | if (shm->addr != NULL) { | |
41 | return NGX_OK; | |
35 | 42 | } |
36 | 43 | |
37 | return NGX_OK; | |
44 | ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, | |
45 | "MapViewOfFile(%uz) failed", shm->size); | |
46 | ||
47 | if (CloseHandle(shm->handle) == 0) { | |
48 | ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, | |
49 | "CloseHandle() failed"); | |
50 | } | |
51 | ||
52 | failed: | |
53 | ||
54 | ngx_free(name); | |
55 | ||
56 | return NGX_ERROR; | |
38 | 57 | } |
39 | 58 | |
40 | 59 |
12 | 12 | |
13 | 13 | |
14 | 14 | typedef struct { |
15 | u_char *addr; | |
16 | size_t size; | |
17 | ngx_str_t name; | |
18 | HANDLE handle; | |
19 | ngx_log_t *log; | |
15 | u_char *addr; | |
16 | size_t size; | |
17 | ngx_str_t name; | |
18 | HANDLE handle; | |
19 | ngx_log_t *log; | |
20 | ngx_uint_t exists; /* unsigned exists:1; */ | |
20 | 21 | } ngx_shm_t; |
21 | 22 | |
22 | 23 |
16 | 16 | ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; |
17 | 17 | |
18 | 18 | ngx_fd_t ngx_stderr_fileno; |
19 | char ngx_unique[NGX_INT32_LEN + 1]; | |
19 | 20 | |
20 | 21 | |
21 | 22 | ngx_os_io_t ngx_os_io = { |
59 | 60 | DWORD bytes; |
60 | 61 | SOCKET s; |
61 | 62 | WSADATA wsd; |
63 | ngx_err_t err; | |
62 | 64 | ngx_uint_t n; |
63 | 65 | SYSTEM_INFO si; |
64 | 66 | |
204 | 206 | ngx_close_socket_n " failed"); |
205 | 207 | } |
206 | 208 | |
209 | if (GetEnvironmentVariable("nginx_unique", ngx_unique, NGX_INT32_LEN + 1) | |
210 | != 0) | |
211 | { | |
212 | ngx_process = NGX_PROCESS_WORKER; | |
213 | ||
214 | } else { | |
215 | err = ngx_errno; | |
216 | ||
217 | if (err != ERROR_ENVVAR_NOT_FOUND) { | |
218 | ngx_log_error(NGX_LOG_EMERG, log, err, | |
219 | "GetEnvironmentVariable(\"nginx_unique\") failed"); | |
220 | return NGX_ERROR; | |
221 | } | |
222 | ||
223 | ngx_sprintf((u_char *) ngx_unique, "%P%Z", ngx_pid); | |
224 | } | |
225 | ||
207 | 226 | return NGX_OK; |
208 | 227 | } |
209 | 228 |