support attaching to an existent Win32 shared memory

This commit is contained in:
Igor Sysoev 2009-04-18 19:27:28 +00:00
parent 6ac68bcc4c
commit f7a08d5f9a
13 changed files with 222 additions and 157 deletions

View File

@ -9,9 +9,11 @@
#include <ngx_event.h> #include <ngx_event.h>
static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
static void ngx_destroy_cycle_pools(ngx_conf_t *conf); static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2); static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2);
static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
ngx_shm_zone_t *shm_zone);
static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
static void ngx_clean_old_cycles(ngx_event_t *ev); static void ngx_clean_old_cycles(ngx_event_t *ev);
@ -44,7 +46,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
{ {
void *rv; void *rv;
char **senv, **env; char **senv, **env;
u_char *lock_file;
ngx_uint_t i, n; ngx_uint_t i, n;
ngx_log_t *log; ngx_log_t *log;
ngx_time_t *tp; ngx_time_t *tp;
@ -52,7 +53,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
ngx_pool_t *pool; ngx_pool_t *pool;
ngx_cycle_t *cycle, **old; ngx_cycle_t *cycle, **old;
ngx_shm_zone_t *shm_zone, *oshm_zone; ngx_shm_zone_t *shm_zone, *oshm_zone;
ngx_slab_pool_t *shpool;
ngx_list_part_t *part, *opart; ngx_list_part_t *part, *opart;
ngx_open_file_t *file; ngx_open_file_t *file;
ngx_listening_t *ls, *nls; ngx_listening_t *ls, *nls;
@ -470,39 +470,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
goto failed; goto failed;
} }
shpool = (ngx_slab_pool_t *) shm_zone[i].shm.addr; if (!shm_zone[i].shm.exists) {
shpool->end = shm_zone[i].shm.addr + shm_zone[i].shm.size; if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
shpool->min_shift = 3;
#if (NGX_HAVE_ATOMIC_OPS)
lock_file = NULL;
#else
lock_file = ngx_pnalloc(cycle->pool,
cycle->lock_file.len + shm_zone[i].shm.name.len);
if (lock_file == NULL) {
goto failed; goto failed;
} }
(void) ngx_cpystrn(ngx_cpymem(lock_file, cycle->lock_file.data,
cycle->lock_file.len),
shm_zone[i].shm.name.data,
shm_zone[i].shm.name.len + 1);
#endif
if (ngx_shmtx_create(&shpool->mutex, (void *) &shpool->lock, lock_file)
!= NGX_OK)
{
goto failed;
} }
ngx_slab_init(shpool);
if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
goto failed; goto failed;
} }
@ -919,6 +893,42 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
} }
static ngx_int_t
ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
{
u_char *file;
ngx_slab_pool_t *sp;
sp = (ngx_slab_pool_t *) zn->shm.addr;
sp->end = zn->shm.addr + zn->shm.size;
sp->min_shift = 3;
#if (NGX_HAVE_ATOMIC_OPS)
file = NULL;
#else
file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len);
if (file == NULL) {
return NGX_ERROR;
}
(void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);
#endif
if (ngx_shmtx_create(&sp->mutex, (void *) &sp->lock, file) != NGX_OK) {
return NGX_ERROR;
}
ngx_slab_init(sp);
return NGX_OK;
}
#if !(NGX_WIN32) #if !(NGX_WIN32)
ngx_int_t ngx_int_t
@ -1216,6 +1226,7 @@ ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
shm_zone->shm.log = cf->cycle->log; shm_zone->shm.log = cf->cycle->log;
shm_zone->shm.size = size; shm_zone->shm.size = size;
shm_zone->shm.name = *name; shm_zone->shm.name = *name;
shm_zone->shm.exists = 0;
shm_zone->init = NULL; shm_zone->init = NULL;
shm_zone->tag = tag; shm_zone->tag = tag;

View File

@ -37,6 +37,8 @@ typedef struct {
u_char *log_ctx; u_char *log_ctx;
u_char zero; u_char zero;
void *data;
} ngx_slab_pool_t; } ngx_slab_pool_t;

View File

@ -506,6 +506,8 @@ ngx_event_module_init(ngx_cycle_t *cycle)
#endif #endif
shm.size = size; shm.size = size;
shm.name.len = sizeof("nginx_shared_zone");
shm.name.data = (u_char *) "nginx_shared_zone";
shm.log = cycle->log; shm.log = cycle->log;
if (ngx_shm_alloc(&shm) != NGX_OK) { if (ngx_shm_alloc(&shm) != NGX_OK) {
@ -535,7 +537,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
#endif #endif
*ngx_connection_counter = 1; (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"counter: %p, %d", "counter: %p, %d",

View File

@ -1421,6 +1421,11 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
return NGX_OK; return NGX_OK;
} }
if (shm_zone->shm.exists) {
shm_zone->data = data;
return NGX_OK;
}
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
@ -1428,6 +1433,9 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
return NGX_ERROR; return NGX_ERROR;
} }
shpool->data = cache;
shm_zone->data = cache;
ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
ngx_ssl_session_rbtree_insert_value); ngx_ssl_session_rbtree_insert_value);
@ -1443,8 +1451,6 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z", ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z",
&shm_zone->shm.name); &shm_zone->shm.name);
shm_zone->data = cache;
return NGX_OK; return NGX_OK;
} }

View File

@ -15,16 +15,24 @@ typedef struct {
u_short len; u_short len;
ngx_queue_t queue; ngx_queue_t queue;
ngx_msec_t last; ngx_msec_t last;
ngx_uint_t excess; /* integer value, 1 corresponds to 0.001 r/s */ /* integer value, 1 corresponds to 0.001 r/s */
ngx_uint_t excess;
u_char data[1]; u_char data[1];
} ngx_http_limit_req_node_t; } ngx_http_limit_req_node_t;
typedef struct { typedef struct {
ngx_rbtree_t *rbtree; ngx_rbtree_t rbtree;
ngx_queue_t *queue; ngx_rbtree_node_t sentinel;
ngx_queue_t queue;
} ngx_http_limit_req_shctx_t;
typedef struct {
ngx_http_limit_req_shctx_t *sh;
ngx_slab_pool_t *shpool; ngx_slab_pool_t *shpool;
ngx_uint_t rate; /* integer value, 1 corresponds to 0.001 r/s */ /* integer value, 1 corresponds to 0.001 r/s */
ngx_uint_t rate;
ngx_int_t index; ngx_int_t index;
ngx_str_t var; ngx_str_t var;
} ngx_http_limit_req_ctx_t; } ngx_http_limit_req_ctx_t;
@ -32,7 +40,8 @@ typedef struct {
typedef struct { typedef struct {
ngx_shm_zone_t *shm_zone; ngx_shm_zone_t *shm_zone;
ngx_uint_t burst; /* integer value, 1 corresponds to 0.001 r/s */ /* integer value, 1 corresponds to 0.001 r/s */
ngx_uint_t burst;
ngx_uint_t nodelay;/* unsigned nodelay:1 */ ngx_uint_t nodelay;/* unsigned nodelay:1 */
} ngx_http_limit_req_conf_t; } ngx_http_limit_req_conf_t;
@ -163,7 +172,7 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
if (lr) { if (lr) {
ngx_queue_remove(&lr->queue); ngx_queue_remove(&lr->queue);
ngx_queue_insert_head(ctx->queue, &lr->queue); ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
excess = lr->excess; excess = lr->excess;
@ -239,9 +248,9 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
lr->excess = 0; lr->excess = 0;
ngx_memcpy(lr->data, vv->data, len); ngx_memcpy(lr->data, vv->data, len);
ngx_rbtree_insert(ctx->rbtree, node); ngx_rbtree_insert(&ctx->sh->rbtree, node);
ngx_queue_insert_head(ctx->queue, &lr->queue); ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
done: done:
@ -324,8 +333,8 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
ctx = lrcf->shm_zone->data; ctx = lrcf->shm_zone->data;
node = ctx->rbtree->root; node = ctx->sh->rbtree.root;
sentinel = ctx->rbtree->sentinel; sentinel = ctx->sh->rbtree.sentinel;
while (node != sentinel) { while (node != sentinel) {
@ -411,11 +420,11 @@ ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
while (n < 3) { while (n < 3) {
if (ngx_queue_empty(ctx->queue)) { if (ngx_queue_empty(&ctx->sh->queue)) {
return; return;
} }
q = ngx_queue_last(ctx->queue); q = ngx_queue_last(&ctx->sh->queue);
lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue);
@ -440,7 +449,7 @@ ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
node = (ngx_rbtree_node_t *) node = (ngx_rbtree_node_t *)
((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); ((u_char *) lr - offsetof(ngx_rbtree_node_t, color));
ngx_rbtree_delete(ctx->rbtree, node); ngx_rbtree_delete(&ctx->sh->rbtree, node);
ngx_slab_free_locked(ctx->shpool, node); ngx_slab_free_locked(ctx->shpool, node);
} }
@ -453,7 +462,6 @@ ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
ngx_http_limit_req_ctx_t *octx = data; ngx_http_limit_req_ctx_t *octx = data;
size_t len; size_t len;
ngx_rbtree_node_t *sentinel;
ngx_http_limit_req_ctx_t *ctx; ngx_http_limit_req_ctx_t *ctx;
ctx = shm_zone->data; ctx = shm_zone->data;
@ -467,8 +475,7 @@ ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
return NGX_ERROR; return NGX_ERROR;
} }
ctx->rbtree = octx->rbtree; ctx->sh = octx->sh;
ctx->queue = octx->queue;
ctx->shpool = octx->shpool; ctx->shpool = octx->shpool;
return NGX_OK; return NGX_OK;
@ -476,25 +483,23 @@ ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
ctx->rbtree = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_t)); if (shm_zone->shm.exists) {
if (ctx->rbtree == NULL) { ctx->sh = ctx->shpool->data;
return NGX_OK;
}
ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t));
if (ctx->sh == NULL) {
return NGX_ERROR; return NGX_ERROR;
} }
sentinel = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_node_t)); ctx->shpool->data = ctx->sh;
if (sentinel == NULL) {
return NGX_ERROR;
}
ngx_rbtree_init(ctx->rbtree, sentinel, ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel,
ngx_http_limit_req_rbtree_insert_value); ngx_http_limit_req_rbtree_insert_value);
ctx->queue = ngx_slab_alloc(ctx->shpool, sizeof(ngx_queue_t)); ngx_queue_init(&ctx->sh->queue);
if (ctx->queue == NULL) {
return NGX_ERROR;
}
ngx_queue_init(ctx->queue);
len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len; len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len;

View File

@ -339,11 +339,19 @@ ngx_http_limit_zone_init_zone(ngx_shm_zone_t *shm_zone, void *data)
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
if (shm_zone->shm.exists) {
ctx->rbtree = shpool->data;
return NGX_OK;
}
ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
if (ctx->rbtree == NULL) { if (ctx->rbtree == NULL) {
return NGX_ERROR; return NGX_ERROR;
} }
shpool->data = ctx->rbtree;
sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
if (sentinel == NULL) { if (sentinel == NULL) {
return NGX_ERROR; return NGX_ERROR;

View File

@ -94,16 +94,21 @@ typedef struct {
} ngx_http_file_cache_header_t; } ngx_http_file_cache_header_t;
typedef struct {
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
ngx_queue_t queue;
ngx_atomic_t cold;
off_t size;
} ngx_http_file_cache_sh_t;
struct ngx_http_file_cache_s { struct ngx_http_file_cache_s {
ngx_rbtree_t *rbtree; ngx_http_file_cache_sh_t *sh;
ngx_queue_t *queue;
ngx_slab_pool_t *shpool; ngx_slab_pool_t *shpool;
ngx_path_t *path; ngx_path_t *path;
ngx_atomic_t *cold;
off_t *size;
off_t max_size; off_t max_size;
size_t bsize; size_t bsize;

View File

@ -44,7 +44,6 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
ngx_http_file_cache_t *ocache = data; ngx_http_file_cache_t *ocache = data;
size_t len; size_t len;
ngx_rbtree_node_t *sentinel;
ngx_http_file_cache_t *cache; ngx_http_file_cache_t *cache;
cache = shm_zone->data; cache = shm_zone->data;
@ -60,11 +59,9 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
return NGX_ERROR; return NGX_ERROR;
} }
cache->rbtree = ocache->rbtree; cache->sh = ocache->sh;
cache->queue = ocache->queue;
cache->shpool = ocache->shpool; cache->shpool = ocache->shpool;
cache->cold = ocache->cold;
cache->size = ocache->size;
cache->bsize = ocache->bsize; cache->bsize = ocache->bsize;
cache->max_size /= cache->bsize; cache->max_size /= cache->bsize;
@ -74,39 +71,27 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
cache->rbtree = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_t)); if (shm_zone->shm.exists) {
if (cache->rbtree == NULL) { cache->sh = cache->shpool->data;
cache->bsize = ngx_fs_bsize(cache->path->name.data);
return NGX_OK;
}
cache->sh = ngx_slab_alloc(cache->shpool, sizeof(ngx_http_file_cache_sh_t));
if (cache->sh == NULL) {
return NGX_ERROR; return NGX_ERROR;
} }
sentinel = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_node_t)); cache->shpool->data = cache->sh;
if (sentinel == NULL) {
return NGX_ERROR;
}
ngx_rbtree_init(cache->rbtree, sentinel, ngx_rbtree_init(&cache->sh->rbtree, &cache->sh->sentinel,
ngx_http_file_cache_rbtree_insert_value); ngx_http_file_cache_rbtree_insert_value);
cache->queue = ngx_slab_alloc(cache->shpool, sizeof(ngx_queue_t)); ngx_queue_init(&cache->sh->queue);
if (cache->queue == NULL) {
return NGX_ERROR;
}
ngx_queue_init(cache->queue); cache->sh->cold = 1;
cache->sh->size = 0;
cache->cold = ngx_slab_alloc(cache->shpool, sizeof(ngx_atomic_t));
if (cache->cold == NULL) {
return NGX_ERROR;
}
*cache->cold = 1;
cache->size = ngx_slab_alloc(cache->shpool, sizeof(off_t));
if (cache->size == NULL) {
return NGX_ERROR;
}
*cache->size = 0;
cache->bsize = ngx_fs_bsize(cache->path->name.data); cache->bsize = ngx_fs_bsize(cache->path->name.data);
@ -202,7 +187,7 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
return rc; return rc;
} }
cold = *cache->cold; cold = cache->sh->cold;
if (rc == NGX_OK) { if (rc == NGX_OK) {
@ -337,7 +322,7 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
c->node->body_start = c->body_start; c->node->body_start = c->body_start;
c->node->exists = 1; c->node->exists = 1;
*cache->size += (c->length + cache->bsize - 1) / cache->bsize; cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize;
} }
ngx_shmtx_unlock(&cache->shpool->mutex); ngx_shmtx_unlock(&cache->shpool->mutex);
@ -434,7 +419,7 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
ngx_rbtree_insert(cache->rbtree, &fcn->node); ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
renew: renew:
@ -454,7 +439,7 @@ done:
fcn->expire = ngx_time() + cache->inactive; fcn->expire = ngx_time() + cache->inactive;
ngx_queue_insert_head(cache->queue, &fcn->queue); ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
c->uniq = fcn->uniq; c->uniq = fcn->uniq;
c->uses = fcn->uses; c->uses = fcn->uses;
@ -479,8 +464,8 @@ ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key)
ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t)); ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t));
node = cache->rbtree->root; node = cache->sh->rbtree.root;
sentinel = cache->rbtree->sentinel; sentinel = cache->sh->rbtree.sentinel;
while (node != sentinel) { while (node != sentinel) {
@ -663,7 +648,7 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
c->node->length = c->length; c->node->length = c->length;
*cache->size += size; cache->sh->size += size;
if (rc == NGX_OK) { if (rc == NGX_OK) {
c->node->exists = 1; c->node->exists = 1;
@ -828,8 +813,8 @@ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
ngx_shmtx_lock(&cache->shpool->mutex); ngx_shmtx_lock(&cache->shpool->mutex);
for (q = ngx_queue_last(cache->queue); for (q = ngx_queue_last(&cache->sh->queue);
q != ngx_queue_sentinel(cache->queue); q != ngx_queue_sentinel(&cache->sh->queue);
q = ngx_queue_prev(q)) q = ngx_queue_prev(q))
{ {
fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
@ -853,7 +838,7 @@ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
if (!fcn->exists) { if (!fcn->exists) {
ngx_queue_remove(q); ngx_queue_remove(q);
ngx_rbtree_delete(cache->rbtree, &fcn->node); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
ngx_slab_free_locked(cache->shpool, fcn); ngx_slab_free_locked(cache->shpool, fcn);
break; break;
@ -902,12 +887,12 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
for ( ;; ) { for ( ;; ) {
if (ngx_queue_empty(cache->queue)) { if (ngx_queue_empty(&cache->sh->queue)) {
wait = 10; wait = 10;
break; break;
} }
q = ngx_queue_last(cache->queue); q = ngx_queue_last(&cache->sh->queue);
fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
@ -939,7 +924,7 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
*/ */
ngx_queue_remove(q); ngx_queue_remove(q);
ngx_rbtree_delete(cache->rbtree, &fcn->node); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"ignore long locked inactive cache entry %*s, count:%d", "ignore long locked inactive cache entry %*s, count:%d",
@ -951,7 +936,7 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
if (!fcn->exists) { if (!fcn->exists) {
ngx_queue_remove(q); ngx_queue_remove(q);
ngx_rbtree_delete(cache->rbtree, &fcn->node); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
ngx_slab_free_locked(cache->shpool, fcn); ngx_slab_free_locked(cache->shpool, fcn);
continue; continue;
@ -979,7 +964,7 @@ ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q,
fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
*cache->size -= (fcn->length + cache->bsize - 1) / cache->bsize; cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize;
path = cache->path; path = cache->path;
@ -993,7 +978,7 @@ ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q,
ngx_queue_remove(q); ngx_queue_remove(q);
ngx_rbtree_delete(cache->rbtree, &fcn->node); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
ngx_slab_free_locked(cache->shpool, fcn); ngx_slab_free_locked(cache->shpool, fcn);
@ -1024,7 +1009,7 @@ ngx_http_file_cache_manager(void *data)
time_t next; time_t next;
ngx_tree_ctx_t tree; ngx_tree_ctx_t tree;
if (*cache->cold) { if (cache->sh->cold) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"http file cache manager update"); "http file cache manager update");
@ -1045,12 +1030,12 @@ ngx_http_file_cache_manager(void *data)
return 10; return 10;
} }
*cache->cold = 0; cache->sh->cold = 0;
ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
"http file cache: %V %.3fM, bsize: %uz", "http file cache: %V %.3fM, bsize: %uz",
&cache->path->name, &cache->path->name,
((double) *cache->size * cache->bsize) / (1024 * 1024), ((double) cache->sh->size * cache->bsize) / (1024 * 1024),
cache->bsize); cache->bsize);
} }
@ -1062,7 +1047,7 @@ ngx_http_file_cache_manager(void *data)
for ( ;; ) { for ( ;; ) {
ngx_shmtx_lock(&cache->shpool->mutex); ngx_shmtx_lock(&cache->shpool->mutex);
size = *cache->size; size = cache->sh->size;
ngx_shmtx_unlock(&cache->shpool->mutex); ngx_shmtx_unlock(&cache->shpool->mutex);
@ -1245,7 +1230,7 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
ngx_rbtree_insert(cache->rbtree, &fcn->node); ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
fcn->uses = 1; fcn->uses = 1;
fcn->count = 0; fcn->count = 0;
@ -1257,7 +1242,7 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
fcn->body_start = c->body_start; fcn->body_start = c->body_start;
fcn->length = c->length; fcn->length = c->length;
*cache->size += (c->length + cache->bsize - 1) / cache->bsize; cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize;
} else { } else {
ngx_queue_remove(&fcn->queue); ngx_queue_remove(&fcn->queue);
@ -1265,7 +1250,7 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
fcn->expire = ngx_time() + cache->inactive; fcn->expire = ngx_time() + cache->inactive;
ngx_queue_insert_head(cache->queue, &fcn->queue); ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
ngx_shmtx_unlock(&cache->shpool->mutex); ngx_shmtx_unlock(&cache->shpool->mutex);

View File

@ -17,6 +17,7 @@ typedef struct {
size_t size; size_t size;
ngx_str_t name; ngx_str_t name;
ngx_log_t *log; ngx_log_t *log;
ngx_uint_t exists; /* unsigned exists:1; */
} ngx_shm_t; } ngx_shm_t;

View File

@ -54,6 +54,7 @@ extern ngx_uint_t ngx_inherited_nonblocking;
extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
extern ngx_uint_t ngx_win32_version; extern ngx_uint_t ngx_win32_version;
extern ngx_fd_t ngx_stderr_fileno; extern ngx_fd_t ngx_stderr_fileno;
extern char ngx_unique[];

View File

@ -11,19 +11,37 @@
ngx_int_t ngx_int_t
ngx_shm_alloc(ngx_shm_t *shm) ngx_shm_alloc(ngx_shm_t *shm)
{ {
u_char *name;
name = ngx_alloc(shm->name.len + 2 + sizeof(NGX_INT32_LEN), shm->log);
if (name == NULL) {
return NGX_ERROR;
}
ngx_sprintf(name, "%V_%s%Z", &shm->name, ngx_unique);
ngx_set_errno(0);
shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, shm->size, (char *) shm->name.data); 0, shm->size, (char *) name);
if (shm->handle == NULL) { if (shm->handle == NULL) {
ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
"CreateFileMapping(%uz, %s) failed", "CreateFileMapping(%uz, %s) failed",
shm->size, shm->name.data); shm->size, shm->name.data);
return NGX_ERROR; goto failed;
}
if (ngx_errno == ERROR_ALREADY_EXISTS) {
shm->exists = 1;
} }
shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0);
if (shm->addr == NULL) { if (shm->addr != NULL) {
return NGX_OK;
}
ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
"MapViewOfFile(%uz) failed", shm->size); "MapViewOfFile(%uz) failed", shm->size);
@ -32,10 +50,11 @@ ngx_shm_alloc(ngx_shm_t *shm)
"CloseHandle() failed"); "CloseHandle() failed");
} }
return NGX_ERROR; failed:
}
return NGX_OK; ngx_free(name);
return NGX_ERROR;
} }

View File

@ -18,6 +18,7 @@ typedef struct {
ngx_str_t name; ngx_str_t name;
HANDLE handle; HANDLE handle;
ngx_log_t *log; ngx_log_t *log;
ngx_uint_t exists; /* unsigned exists:1; */
} ngx_shm_t; } ngx_shm_t;

View File

@ -17,6 +17,7 @@ ngx_uint_t ngx_inherited_nonblocking = 1;
ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
ngx_fd_t ngx_stderr_fileno; ngx_fd_t ngx_stderr_fileno;
char ngx_unique[NGX_INT32_LEN + 1];
ngx_os_io_t ngx_os_io = { ngx_os_io_t ngx_os_io = {
@ -60,6 +61,7 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
DWORD bytes; DWORD bytes;
SOCKET s; SOCKET s;
WSADATA wsd; WSADATA wsd;
ngx_err_t err;
ngx_uint_t n; ngx_uint_t n;
SYSTEM_INFO si; SYSTEM_INFO si;
@ -205,6 +207,23 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
ngx_close_socket_n " failed"); ngx_close_socket_n " failed");
} }
if (GetEnvironmentVariable("nginx_unique", ngx_unique, NGX_INT32_LEN + 1)
!= 0)
{
ngx_process = NGX_PROCESS_WORKER;
} else {
err = ngx_errno;
if (err != ERROR_ENVVAR_NOT_FOUND) {
ngx_log_error(NGX_LOG_EMERG, log, err,
"GetEnvironmentVariable(\"nginx_unique\") failed");
return NGX_ERROR;
}
ngx_sprintf((u_char *) ngx_unique, "%P%Z", ngx_pid);
}
return NGX_OK; return NGX_OK;
} }