diff --git a/src/cache.c b/src/cache.c index caa71e8a3..03651c8e2 100644 --- a/src/cache.c +++ b/src/cache.c @@ -770,13 +770,10 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms end: - shctx_wrlock(shctx); fb = shctx_row_reserve_hot(shctx, st->first_block, trash.data); if (!fb) { - shctx_wrunlock(shctx); goto no_cache; } - shctx_wrunlock(shctx); ret = shctx_row_data_append(shctx, st->first_block, (unsigned char *)b_head(&trash), b_data(&trash)); @@ -1225,9 +1222,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px, } cache_wrunlock(cache); - shctx_wrlock(shctx); first = shctx_row_reserve_hot(shctx, NULL, sizeof(struct cache_entry)); - shctx_wrunlock(shctx); if (!first) { goto out; } @@ -1327,12 +1322,9 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px, if (set_secondary_key_encoding(htx, object->secondary_key)) goto out; - shctx_wrlock(shctx); if (!shctx_row_reserve_hot(shctx, first, trash.data)) { - shctx_wrunlock(shctx); goto out; } - shctx_wrunlock(shctx); /* cache the headers in a http action because it allows to chose what * to cache, for example you might want to cache a response before diff --git a/src/shctx.c b/src/shctx.c index a9ea4c36c..daf7866c9 100644 --- a/src/shctx.c +++ b/src/shctx.c @@ -35,10 +35,6 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx, BUG_ON(data_len < 0); - /* not enough usable blocks */ - if (data_len > shctx->nbav * shctx->block_size) - goto out; - /* Check the object size limit. */ if (shctx->max_obj_size > 0) { if ((first && first->len + data_len > shctx->max_obj_size) || @@ -66,8 +62,19 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx, } } + shctx_wrlock(shctx); + + /* not enough usable blocks */ + if (data_len > shctx->nbav * shctx->block_size) { + shctx_wrunlock(shctx); + goto out; + } + + if (data_len <= 0 || LIST_ISEMPTY(&shctx->avail)) { - return NULL; + ret = NULL; + shctx_wrunlock(shctx); + goto out; } list_for_each_entry_safe(block, sblock, &shctx->avail, list) { @@ -101,6 +108,8 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx, } } + shctx_wrunlock(shctx); + out: return ret; } diff --git a/src/ssl_sock.c b/src/ssl_sock.c index bcbcb8470..3a8f2481d 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -4239,6 +4239,8 @@ static int sh_ssl_sess_store(unsigned char *s_id, unsigned char *data, int data_ return 0; } + shctx_wrlock(ssl_shctx); + /* STORE the key in the first elem */ sh_ssl_sess = (struct sh_ssl_sess_hdr *)first->data; memcpy(sh_ssl_sess->key_data, s_id, SSL_MAX_SSL_SESSION_ID_LENGTH); @@ -4267,6 +4269,8 @@ static int sh_ssl_sess_store(unsigned char *s_id, unsigned char *data, int data_ shctx_row_reattach(ssl_shctx, first); + shctx_wrunlock(ssl_shctx); + return 1; } @@ -4408,10 +4412,8 @@ int sh_ssl_sess_new_cb(SSL *ssl, SSL_SESSION *sess) i2d_SSL_SESSION(sess, &p); - shctx_wrlock(ssl_shctx); /* store to cache */ sh_ssl_sess_store(encid, encsess, data_len); - shctx_wrunlock(ssl_shctx); err: /* reset original length values */ SSL_SESSION_set1_id(sess, encid, sid_length);