changeset 3755:76e3a93821b1

fix race condition if during reconfiguration two cache managers try to delete old inactive entries: one of them removes a entry just locked by other manager from the queue and the rbtree as long inactive entry, causes the latter manager to segfault leaving cache mutex locked, the bug has been introduced in r3727
author Igor Sysoev <igor@sysoev.ru>
date Thu, 02 Sep 2010 14:31:47 +0000
parents 5f58badd13ed
children 7224d008faaf
files src/http/ngx_http_cache.h src/http/ngx_http_file_cache.c
diffstat 2 files changed, 10 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -43,7 +43,8 @@ typedef struct {
     unsigned                         error:10;
     unsigned                         exists:1;
     unsigned                         updating:1;
-                                     /* 12 unused bits */
+    unsigned                         deleting:1;
+                                     /* 11 unused bits */
 
     ngx_file_uniq_t                  uniq;
     time_t                           expire;
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -582,6 +582,7 @@ ngx_http_file_cache_exists(ngx_http_file
     fcn->uses = 1;
     fcn->count = 1;
     fcn->updating = 0;
+    fcn->deleting = 0;
 
 renew:
 
@@ -1102,6 +1103,10 @@ ngx_http_file_cache_expire(ngx_http_file
             continue;
         }
 
+        if (fcn->deleting) {
+            continue;
+        }
+
         p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
                          sizeof(ngx_rbtree_key_t));
         len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
@@ -1153,6 +1158,7 @@ ngx_http_file_cache_delete(ngx_http_file
         *p = '\0';
 
         fcn->count++;
+        fcn->deleting = 1;
         ngx_shmtx_unlock(&cache->shpool->mutex);
 
         len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
@@ -1168,6 +1174,7 @@ ngx_http_file_cache_delete(ngx_http_file
 
         ngx_shmtx_lock(&cache->shpool->mutex);
         fcn->count--;
+        fcn->deleting = 0;
     }
 
     if (fcn->count == 0) {
@@ -1431,6 +1438,7 @@ ngx_http_file_cache_add(ngx_http_file_ca
         fcn->error = 0;
         fcn->exists = 1;
         fcn->updating = 0;
+        fcn->deleting = 0;
         fcn->uniq = c->uniq;
         fcn->valid_sec = c->valid_sec;
         fcn->body_start = c->body_start;