mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-07 10:18:01 +00:00
BUG/MEDIUM: cache: use key=0 as a condition for freeing
The cache was trying to remove objects from the tree while they were already removed from it. We set the key to 0 as a check for not trying to remove the object from the tree when we are still using the object.
This commit is contained in:
parent
1f49a366fd
commit
0872766e31
26
src/cache.c
26
src/cache.c
@ -81,10 +81,12 @@ struct cache_entry *entry_exist(struct cache *cache, struct cache_entry *new_ent
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
entry = eb32_entry(node, struct cache_entry, eb);
|
entry = eb32_entry(node, struct cache_entry, eb);
|
||||||
if (entry->expire > now.tv_sec)
|
if (entry->expire > now.tv_sec) {
|
||||||
return entry;
|
return entry;
|
||||||
else
|
} else {
|
||||||
eb32_delete(node);
|
eb32_delete(node);
|
||||||
|
entry->eb.key = 0;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -149,6 +151,7 @@ cache_store_http_forward_data(struct stream *s, struct filter *filter,
|
|||||||
{
|
{
|
||||||
struct cache_st *st = filter->ctx;
|
struct cache_st *st = filter->ctx;
|
||||||
struct shared_context *shctx = shctx_ptr((struct cache *)filter->config->conf);
|
struct shared_context *shctx = shctx_ptr((struct cache *)filter->config->conf);
|
||||||
|
struct cache_entry *object;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -173,9 +176,11 @@ cache_store_http_forward_data(struct stream *s, struct filter *filter,
|
|||||||
/* disable buffering if too much data (never greater than a buffer size */
|
/* disable buffering if too much data (never greater than a buffer size */
|
||||||
if (len - st->hdrs_len > global.tune.bufsize - global.tune.maxrewrite - st->first_block->len) {
|
if (len - st->hdrs_len > global.tune.bufsize - global.tune.maxrewrite - st->first_block->len) {
|
||||||
disable_cache:
|
disable_cache:
|
||||||
|
object = (struct cache_entry *)st->first_block->data;
|
||||||
filter->ctx = NULL; /* disable cache */
|
filter->ctx = NULL; /* disable cache */
|
||||||
shctx_lock(shctx);
|
shctx_lock(shctx);
|
||||||
shctx_row_dec_hot(shctx, st->first_block);
|
shctx_row_dec_hot(shctx, st->first_block);
|
||||||
|
object->eb.key = 0;
|
||||||
shctx_unlock(shctx);
|
shctx_unlock(shctx);
|
||||||
pool_free2(pool2_cache_st, st);
|
pool_free2(pool2_cache_st, st);
|
||||||
} else {
|
} else {
|
||||||
@ -221,11 +226,10 @@ cache_store_http_end(struct stream *s, struct filter *filter,
|
|||||||
* doesn't, the blocks will be reused anyway */
|
* doesn't, the blocks will be reused anyway */
|
||||||
|
|
||||||
shctx_lock(shctx);
|
shctx_lock(shctx);
|
||||||
eb32_insert(&cache->entries, &object->eb);
|
if (eb32_insert(&cache->entries, &object->eb) != &object->eb) {
|
||||||
shctx_unlock(shctx);
|
object->eb.key = 0;
|
||||||
|
}
|
||||||
/* remove from the hotlist */
|
/* remove from the hotlist */
|
||||||
shctx_lock(shctx);
|
|
||||||
shctx_row_dec_hot(shctx, st->first_block);
|
shctx_row_dec_hot(shctx, st->first_block);
|
||||||
shctx_unlock(shctx);
|
shctx_unlock(shctx);
|
||||||
|
|
||||||
@ -343,7 +347,10 @@ static void cache_free_blocks(struct shared_block *first, struct shared_block *b
|
|||||||
{
|
{
|
||||||
if (first == block) {
|
if (first == block) {
|
||||||
struct cache_entry *object = (struct cache_entry *)first->data;
|
struct cache_entry *object = (struct cache_entry *)first->data;
|
||||||
eb32_delete(&object->eb);
|
if (object->eb.key) {
|
||||||
|
eb32_delete(&object->eb);
|
||||||
|
object->eb.key = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,6 +450,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
|
|||||||
if (entry_exist((struct cache *)rule->arg.act.p[0], object)) {
|
if (entry_exist((struct cache *)rule->arg.act.p[0], object)) {
|
||||||
shctx_unlock(shctx);
|
shctx_unlock(shctx);
|
||||||
if (filter->ctx) {
|
if (filter->ctx) {
|
||||||
|
object->eb.key = 0;
|
||||||
pool_free2(pool2_cache_st, filter->ctx);
|
pool_free2(pool2_cache_st, filter->ctx);
|
||||||
filter->ctx = NULL;
|
filter->ctx = NULL;
|
||||||
}
|
}
|
||||||
@ -463,7 +471,11 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
|
|||||||
out:
|
out:
|
||||||
/* if does not cache */
|
/* if does not cache */
|
||||||
if (first) {
|
if (first) {
|
||||||
|
object = (struct cache_entry *)first->data;
|
||||||
|
|
||||||
shctx_lock(shctx);
|
shctx_lock(shctx);
|
||||||
|
first->len = 0;
|
||||||
|
object->eb.key = 0;
|
||||||
shctx_row_dec_hot(shctx, first);
|
shctx_row_dec_hot(shctx, first);
|
||||||
shctx_unlock(shctx);
|
shctx_unlock(shctx);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user