support attaching to an existent Win32 shared memory
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index ee5ac52..124e051 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -9,9 +9,11 @@
#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 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 @@
{
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_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 @@
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;
- 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;
+ 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 @@
}
+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 @@
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
index 348da81..89c4687 100644
--- a/src/core/ngx_slab.h
+++ b/src/core/ngx_slab.h
@@ -37,6 +37,8 @@
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
index 1f2516a..1f8693a 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -506,6 +506,8 @@
#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 @@
#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
index 2ab3f16..1935d4c 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1421,6 +1421,11 @@
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 @@
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_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
index 62bacaf..3d20b29 100644
--- 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 @@
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 @@
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 @@
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 @@
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 @@
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_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 @@
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 @@
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) {
+ if (shm_zone->shm.exists) {
+ 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;
}
- sentinel = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_node_t));
- if (sentinel == NULL) {
- return NGX_ERROR;
- }
+ ctx->shpool->data = ctx->sh;
- ngx_rbtree_init(ctx->rbtree, sentinel,
+ 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
index b32c3da..e11e081 100644
--- a/src/http/modules/ngx_http_limit_zone_module.c
+++ b/src/http/modules/ngx_http_limit_zone_module.c
@@ -339,11 +339,19 @@
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
index f84c618..232f096 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -94,16 +94,21 @@
} 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
index 18794d8..23e3503 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -44,7 +44,6 @@
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 @@
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 @@
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) {
+ if (shm_zone->shm.exists) {
+ 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;
}
- sentinel = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_node_t));
- if (sentinel == NULL) {
- return NGX_ERROR;
- }
+ cache->shpool->data = cache->sh;
- ngx_rbtree_init(cache->rbtree, sentinel,
+ 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->sh->queue);
- ngx_queue_init(cache->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 @@
return rc;
}
- cold = *cache->cold;
+ cold = cache->sh->cold;
if (rc == NGX_OK) {
@@ -337,7 +322,7 @@
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_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 @@
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_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 @@
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_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 @@
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 @@
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_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 @@
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 @@
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_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 @@
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 @@
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 @@
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_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 @@
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 @@
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
index d626802..b5f6697 100644
--- 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
index 93ec3ff..2124ab8 100644
--- a/src/os/win32/ngx_os.h
+++ b/src/os/win32/ngx_os.h
@@ -54,6 +54,7 @@
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
index 62e8585..12837f7 100644
--- 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
index 7bd6d62..57271a4 100644
--- 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
index 5ceb7a8..f451311 100644
--- a/src/os/win32/ngx_win32_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -17,6 +17,7 @@
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 @@
DWORD bytes;
SOCKET s;
WSADATA wsd;
+ ngx_err_t err;
ngx_uint_t n;
SYSTEM_INFO si;
@@ -205,6 +207,23 @@
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;
}