# HG changeset patch # User Igor Sysoev # Date 1240082848 0 # Node ID b3b8c66bd52006c656f879a91c05f0f89286739a # Parent 9237cf8b400bed1cc46f5a268c140a78ba1df978 support attaching to an existent Win32 shared memory diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -9,9 +9,11 @@ #include -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 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); @@ -44,7 +46,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) { void *rv; char **senv, **env; - u_char *lock_file; ngx_uint_t i, n; ngx_log_t *log; ngx_time_t *tp; @@ -52,7 +53,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_pool_t *pool; ngx_cycle_t *cycle, **old; ngx_shm_zone_t *shm_zone, *oshm_zone; - ngx_slab_pool_t *shpool; ngx_list_part_t *part, *opart; ngx_open_file_t *file; ngx_listening_t *ls, *nls; @@ -470,39 +470,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) goto failed; } - shpool = (ngx_slab_pool_t *) shm_zone[i].shm.addr; - - shpool->end = shm_zone[i].shm.addr + shm_zone[i].shm.size; - 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 (!shm_zone[i].shm.exists) { - if (lock_file == NULL) { - goto failed; + if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { + 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) { goto failed; } @@ -919,6 +893,42 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s } +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) ngx_int_t @@ -1216,6 +1226,7 @@ ngx_shared_memory_add(ngx_conf_t *cf, ng shm_zone->shm.log = cf->cycle->log; shm_zone->shm.size = size; shm_zone->shm.name = *name; + shm_zone->shm.exists = 0; shm_zone->init = NULL; shm_zone->tag = tag; diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h --- a/src/core/ngx_slab.h +++ b/src/core/ngx_slab.h @@ -37,6 +37,8 @@ typedef struct { u_char *log_ctx; u_char zero; + + void *data; } ngx_slab_pool_t; diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -506,6 +506,8 @@ ngx_event_module_init(ngx_cycle_t *cycle #endif shm.size = size; + shm.name.len = sizeof("nginx_shared_zone"); + shm.name.data = (u_char *) "nginx_shared_zone"; shm.log = cycle->log; if (ngx_shm_alloc(&shm) != NGX_OK) { @@ -535,7 +537,7 @@ ngx_event_module_init(ngx_cycle_t *cycle #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, "counter: %p, %d", diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1421,6 +1421,11 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ return NGX_OK; } + if (shm_zone->shm.exists) { + shm_zone->data = data; + return NGX_OK; + } + shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); @@ -1428,6 +1433,9 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ return NGX_ERROR; } + shpool->data = cache; + shm_zone->data = cache; + ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, ngx_ssl_session_rbtree_insert_value); @@ -1443,8 +1451,6 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z", &shm_zone->shm.name); - shm_zone->data = cache; - return NGX_OK; } diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -10,30 +10,39 @@ typedef struct { - u_char color; - u_char dummy; - u_short len; - ngx_queue_t queue; - ngx_msec_t last; - ngx_uint_t excess; /* integer value, 1 corresponds to 0.001 r/s */ - u_char data[1]; + u_char color; + u_char dummy; + u_short len; + ngx_queue_t queue; + ngx_msec_t last; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t excess; + u_char data[1]; } ngx_http_limit_req_node_t; typedef struct { - ngx_rbtree_t *rbtree; - ngx_queue_t *queue; - ngx_slab_pool_t *shpool; - ngx_uint_t rate; /* integer value, 1 corresponds to 0.001 r/s */ - ngx_int_t index; - ngx_str_t var; + ngx_rbtree_t rbtree; + 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; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t rate; + ngx_int_t index; + ngx_str_t var; } ngx_http_limit_req_ctx_t; typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_uint_t burst; /* integer value, 1 corresponds to 0.001 r/s */ - ngx_uint_t nodelay;/* unsigned nodelay:1 */ + ngx_shm_zone_t *shm_zone; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t burst; + ngx_uint_t nodelay;/* unsigned nodelay:1 */ } ngx_http_limit_req_conf_t; @@ -163,7 +172,7 @@ ngx_http_limit_req_handler(ngx_http_requ if (lr) { 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; @@ -239,9 +248,9 @@ ngx_http_limit_req_handler(ngx_http_requ lr->excess = 0; 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: @@ -324,8 +333,8 @@ ngx_http_limit_req_lookup(ngx_http_limit ctx = lrcf->shm_zone->data; - node = ctx->rbtree->root; - sentinel = ctx->rbtree->sentinel; + node = ctx->sh->rbtree.root; + sentinel = ctx->sh->rbtree.sentinel; while (node != sentinel) { @@ -411,11 +420,11 @@ ngx_http_limit_req_expire(ngx_http_limit while (n < 3) { - if (ngx_queue_empty(ctx->queue)) { + if (ngx_queue_empty(&ctx->sh->queue)) { 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); @@ -440,7 +449,7 @@ ngx_http_limit_req_expire(ngx_http_limit node = (ngx_rbtree_node_t *) ((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); } @@ -453,7 +462,6 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ngx_http_limit_req_ctx_t *octx = data; size_t len; - ngx_rbtree_node_t *sentinel; ngx_http_limit_req_ctx_t *ctx; ctx = shm_zone->data; @@ -467,8 +475,7 @@ ngx_http_limit_req_init_zone(ngx_shm_zon return NGX_ERROR; } - ctx->rbtree = octx->rbtree; - ctx->queue = octx->queue; + ctx->sh = octx->sh; ctx->shpool = octx->shpool; return NGX_OK; @@ -476,25 +483,23 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - ctx->rbtree = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_t)); - if (ctx->rbtree == NULL) { - return NGX_ERROR; + if (shm_zone->shm.exists) { + ctx->sh = ctx->shpool->data; + + return NGX_OK; } - sentinel = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { + ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t)); + if (ctx->sh == NULL) { return NGX_ERROR; } - ngx_rbtree_init(ctx->rbtree, sentinel, + ctx->shpool->data = ctx->sh; + + ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel, ngx_http_limit_req_rbtree_insert_value); - ctx->queue = ngx_slab_alloc(ctx->shpool, sizeof(ngx_queue_t)); - if (ctx->queue == NULL) { - return NGX_ERROR; - } - - ngx_queue_init(ctx->queue); + ngx_queue_init(&ctx->sh->queue); len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len; diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c --- a/src/http/modules/ngx_http_limit_zone_module.c +++ b/src/http/modules/ngx_http_limit_zone_module.c @@ -339,11 +339,19 @@ ngx_http_limit_zone_init_zone(ngx_shm_zo 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)); if (ctx->rbtree == NULL) { return NGX_ERROR; } + shpool->data = ctx->rbtree; + sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); if (sentinel == NULL) { return NGX_ERROR; diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -94,16 +94,21 @@ typedef struct { } 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 { - ngx_rbtree_t *rbtree; - ngx_queue_t *queue; + ngx_http_file_cache_sh_t *sh; ngx_slab_pool_t *shpool; ngx_path_t *path; - ngx_atomic_t *cold; - off_t *size; - off_t max_size; size_t bsize; diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -44,7 +44,6 @@ ngx_http_file_cache_init(ngx_shm_zone_t ngx_http_file_cache_t *ocache = data; size_t len; - ngx_rbtree_node_t *sentinel; ngx_http_file_cache_t *cache; cache = shm_zone->data; @@ -60,11 +59,9 @@ ngx_http_file_cache_init(ngx_shm_zone_t return NGX_ERROR; } - cache->rbtree = ocache->rbtree; - cache->queue = ocache->queue; + cache->sh = ocache->sh; + cache->shpool = ocache->shpool; - cache->cold = ocache->cold; - cache->size = ocache->size; cache->bsize = ocache->bsize; cache->max_size /= cache->bsize; @@ -74,39 +71,27 @@ ngx_http_file_cache_init(ngx_shm_zone_t cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - cache->rbtree = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_t)); - if (cache->rbtree == NULL) { - return NGX_ERROR; + if (shm_zone->shm.exists) { + cache->sh = cache->shpool->data; + cache->bsize = ngx_fs_bsize(cache->path->name.data); + + return NGX_OK; } - sentinel = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { + cache->sh = ngx_slab_alloc(cache->shpool, sizeof(ngx_http_file_cache_sh_t)); + if (cache->sh == NULL) { return NGX_ERROR; } - ngx_rbtree_init(cache->rbtree, sentinel, + cache->shpool->data = cache->sh; + + ngx_rbtree_init(&cache->sh->rbtree, &cache->sh->sentinel, ngx_http_file_cache_rbtree_insert_value); - cache->queue = ngx_slab_alloc(cache->shpool, sizeof(ngx_queue_t)); - if (cache->queue == NULL) { - return NGX_ERROR; - } - - ngx_queue_init(cache->queue); + ngx_queue_init(&cache->sh->queue); - 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->sh->cold = 1; + cache->sh->size = 0; cache->bsize = ngx_fs_bsize(cache->path->name.data); @@ -202,7 +187,7 @@ ngx_http_file_cache_open(ngx_http_reques return rc; } - cold = *cache->cold; + cold = cache->sh->cold; if (rc == NGX_OK) { @@ -337,7 +322,7 @@ ngx_http_file_cache_open(ngx_http_reques c->node->body_start = c->body_start; 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); @@ -434,7 +419,7 @@ ngx_http_file_cache_exists(ngx_http_file ngx_memcpy(fcn->key, &c->key[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: @@ -454,7 +439,7 @@ done: 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->uses = fcn->uses; @@ -479,8 +464,8 @@ ngx_http_file_cache_lookup(ngx_http_file ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t)); - node = cache->rbtree->root; - sentinel = cache->rbtree->sentinel; + node = cache->sh->rbtree.root; + sentinel = cache->sh->rbtree.sentinel; while (node != sentinel) { @@ -663,7 +648,7 @@ ngx_http_file_cache_update(ngx_http_requ c->node->length = c->length; - *cache->size += size; + cache->sh->size += size; if (rc == NGX_OK) { c->node->exists = 1; @@ -828,8 +813,8 @@ ngx_http_file_cache_forced_expire(ngx_ht ngx_shmtx_lock(&cache->shpool->mutex); - for (q = ngx_queue_last(cache->queue); - q != ngx_queue_sentinel(cache->queue); + for (q = ngx_queue_last(&cache->sh->queue); + q != ngx_queue_sentinel(&cache->sh->queue); q = ngx_queue_prev(q)) { fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); @@ -853,7 +838,7 @@ ngx_http_file_cache_forced_expire(ngx_ht if (!fcn->exists) { 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); break; @@ -902,12 +887,12 @@ ngx_http_file_cache_expire(ngx_http_file for ( ;; ) { - if (ngx_queue_empty(cache->queue)) { + if (ngx_queue_empty(&cache->sh->queue)) { wait = 10; 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); @@ -939,7 +924,7 @@ ngx_http_file_cache_expire(ngx_http_file */ 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, "ignore long locked inactive cache entry %*s, count:%d", @@ -951,7 +936,7 @@ ngx_http_file_cache_expire(ngx_http_file if (!fcn->exists) { 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); continue; @@ -979,7 +964,7 @@ ngx_http_file_cache_delete(ngx_http_file 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; @@ -993,7 +978,7 @@ ngx_http_file_cache_delete(ngx_http_file 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); @@ -1024,7 +1009,7 @@ ngx_http_file_cache_manager(void *data) time_t next; ngx_tree_ctx_t tree; - if (*cache->cold) { + if (cache->sh->cold) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache manager update"); @@ -1045,12 +1030,12 @@ ngx_http_file_cache_manager(void *data) return 10; } - *cache->cold = 0; + cache->sh->cold = 0; ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, "http file cache: %V %.3fM, bsize: %uz", &cache->path->name, - ((double) *cache->size * cache->bsize) / (1024 * 1024), + ((double) cache->sh->size * cache->bsize) / (1024 * 1024), cache->bsize); } @@ -1062,7 +1047,7 @@ ngx_http_file_cache_manager(void *data) for ( ;; ) { ngx_shmtx_lock(&cache->shpool->mutex); - size = *cache->size; + size = cache->sh->size; ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1245,7 +1230,7 @@ ngx_http_file_cache_add(ngx_http_file_ca ngx_memcpy(fcn->key, &c->key[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->count = 0; @@ -1257,7 +1242,7 @@ ngx_http_file_cache_add(ngx_http_file_ca fcn->body_start = c->body_start; fcn->length = c->length; - *cache->size += (c->length + cache->bsize - 1) / cache->bsize; + cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize; } else { ngx_queue_remove(&fcn->queue); @@ -1265,7 +1250,7 @@ ngx_http_file_cache_add(ngx_http_file_ca 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); diff --git a/src/os/unix/ngx_shmem.h b/src/os/unix/ngx_shmem.h --- a/src/os/unix/ngx_shmem.h +++ b/src/os/unix/ngx_shmem.h @@ -13,10 +13,11 @@ typedef struct { - u_char *addr; - size_t size; - ngx_str_t name; - ngx_log_t *log; + u_char *addr; + size_t size; + ngx_str_t name; + ngx_log_t *log; + ngx_uint_t exists; /* unsigned exists:1; */ } ngx_shm_t; diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h --- a/src/os/win32/ngx_os.h +++ b/src/os/win32/ngx_os.h @@ -54,6 +54,7 @@ extern ngx_uint_t ngx_inherited_nonblo extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; extern ngx_uint_t ngx_win32_version; extern ngx_fd_t ngx_stderr_fileno; +extern char ngx_unique[]; diff --git a/src/os/win32/ngx_shmem.c b/src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c +++ b/src/os/win32/ngx_shmem.c @@ -11,31 +11,50 @@ ngx_int_t 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, - 0, shm->size, (char *) shm->name.data); + 0, shm->size, (char *) name); if (shm->handle == NULL) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "CreateFileMapping(%uz, %s) failed", 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); - if (shm->addr == NULL) { - ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, - "MapViewOfFile(%uz) failed", shm->size); - - if (CloseHandle(shm->handle) == 0) { - ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, - "CloseHandle() failed"); - } - - return NGX_ERROR; + if (shm->addr != NULL) { + return NGX_OK; } - return NGX_OK; + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "MapViewOfFile(%uz) failed", shm->size); + + if (CloseHandle(shm->handle) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "CloseHandle() failed"); + } + +failed: + + ngx_free(name); + + return NGX_ERROR; } diff --git a/src/os/win32/ngx_shmem.h b/src/os/win32/ngx_shmem.h --- a/src/os/win32/ngx_shmem.h +++ b/src/os/win32/ngx_shmem.h @@ -13,11 +13,12 @@ typedef struct { - u_char *addr; - size_t size; - ngx_str_t name; - HANDLE handle; - ngx_log_t *log; + u_char *addr; + size_t size; + ngx_str_t name; + HANDLE handle; + ngx_log_t *log; + ngx_uint_t exists; /* unsigned exists:1; */ } ngx_shm_t; diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c +++ b/src/os/win32/ngx_win32_init.c @@ -17,6 +17,7 @@ ngx_uint_t ngx_inherited_nonblocking = ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; ngx_fd_t ngx_stderr_fileno; +char ngx_unique[NGX_INT32_LEN + 1]; ngx_os_io_t ngx_os_io = { @@ -60,6 +61,7 @@ ngx_int_t ngx_os_init(ngx_log_t *log) DWORD bytes; SOCKET s; WSADATA wsd; + ngx_err_t err; ngx_uint_t n; SYSTEM_INFO si; @@ -205,6 +207,23 @@ ngx_int_t ngx_os_init(ngx_log_t *log) 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; }