Mercurial > hg > nginx-quic
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 |