comparison src/http/ngx_http_file_cache.c @ 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 77b18d36d123
children 46938b7418c6
comparison
equal deleted inserted replaced
3754:5f58badd13ed 3755:76e3a93821b1
580 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); 580 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
581 581
582 fcn->uses = 1; 582 fcn->uses = 1;
583 fcn->count = 1; 583 fcn->count = 1;
584 fcn->updating = 0; 584 fcn->updating = 0;
585 fcn->deleting = 0;
585 586
586 renew: 587 renew:
587 588
588 rc = NGX_DECLINED; 589 rc = NGX_DECLINED;
589 590
1100 if (fcn->count == 0) { 1101 if (fcn->count == 0) {
1101 ngx_http_file_cache_delete(cache, q, name); 1102 ngx_http_file_cache_delete(cache, q, name);
1102 continue; 1103 continue;
1103 } 1104 }
1104 1105
1106 if (fcn->deleting) {
1107 continue;
1108 }
1109
1105 p = ngx_hex_dump(key, (u_char *) &fcn->node.key, 1110 p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
1106 sizeof(ngx_rbtree_key_t)); 1111 sizeof(ngx_rbtree_key_t));
1107 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); 1112 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1108 (void) ngx_hex_dump(p, fcn->key, len); 1113 (void) ngx_hex_dump(p, fcn->key, len);
1109 1114
1151 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); 1156 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1152 p = ngx_hex_dump(p, fcn->key, len); 1157 p = ngx_hex_dump(p, fcn->key, len);
1153 *p = '\0'; 1158 *p = '\0';
1154 1159
1155 fcn->count++; 1160 fcn->count++;
1161 fcn->deleting = 1;
1156 ngx_shmtx_unlock(&cache->shpool->mutex); 1162 ngx_shmtx_unlock(&cache->shpool->mutex);
1157 1163
1158 len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; 1164 len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
1159 ngx_create_hashed_filename(path, name, len); 1165 ngx_create_hashed_filename(path, name, len);
1160 1166
1166 ngx_delete_file_n " \"%s\" failed", name); 1172 ngx_delete_file_n " \"%s\" failed", name);
1167 } 1173 }
1168 1174
1169 ngx_shmtx_lock(&cache->shpool->mutex); 1175 ngx_shmtx_lock(&cache->shpool->mutex);
1170 fcn->count--; 1176 fcn->count--;
1177 fcn->deleting = 0;
1171 } 1178 }
1172 1179
1173 if (fcn->count == 0) { 1180 if (fcn->count == 0) {
1174 ngx_queue_remove(q); 1181 ngx_queue_remove(q);
1175 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); 1182 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1429 fcn->count = 0; 1436 fcn->count = 0;
1430 fcn->valid_msec = c->valid_msec; 1437 fcn->valid_msec = c->valid_msec;
1431 fcn->error = 0; 1438 fcn->error = 0;
1432 fcn->exists = 1; 1439 fcn->exists = 1;
1433 fcn->updating = 0; 1440 fcn->updating = 0;
1441 fcn->deleting = 0;
1434 fcn->uniq = c->uniq; 1442 fcn->uniq = c->uniq;
1435 fcn->valid_sec = c->valid_sec; 1443 fcn->valid_sec = c->valid_sec;
1436 fcn->body_start = c->body_start; 1444 fcn->body_start = c->body_start;
1437 fcn->length = c->length; 1445 fcn->length = c->length;
1438 1446