mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
[MEDIUM] stick-tables: add a reference counter to each entry
We'll soon have to maintain links from sessions to entries, so let's add a refcount in entries to avoid purging them if it's not null.
This commit is contained in:
parent
cb18364ca7
commit
e7f3d7ab9f
@ -75,6 +75,7 @@ struct stktable_type {
|
|||||||
*/
|
*/
|
||||||
struct stksess {
|
struct stksess {
|
||||||
unsigned int expire; /* session expiration date */
|
unsigned int expire; /* session expiration date */
|
||||||
|
unsigned int ref_cnt; /* reference count, can only purge when zero */
|
||||||
struct eb32_node exp; /* ebtree node used to hold the session in expiration tree */
|
struct eb32_node exp; /* ebtree node used to hold the session in expiration tree */
|
||||||
struct ebmb_node key; /* ebtree node used to hold the session in table */
|
struct ebmb_node key; /* ebtree node used to hold the session in table */
|
||||||
/* WARNING! do not put anything after <keys>, it's used by the key */
|
/* WARNING! do not put anything after <keys>, it's used by the key */
|
||||||
|
@ -64,6 +64,7 @@ void stksess_setkey(struct stktable *t, struct stksess *ts, struct stktable_key
|
|||||||
static struct stksess *stksess_init(struct stktable *t, struct stksess * ts)
|
static struct stksess *stksess_init(struct stktable *t, struct stksess * ts)
|
||||||
{
|
{
|
||||||
memset((void *)ts - t->data_size, 0, t->data_size);
|
memset((void *)ts - t->data_size, 0, t->data_size);
|
||||||
|
ts->ref_cnt = 0;
|
||||||
ts->key.node.leaf_p = NULL;
|
ts->key.node.leaf_p = NULL;
|
||||||
ts->exp.node.leaf_p = NULL;
|
ts->exp.node.leaf_p = NULL;
|
||||||
return ts;
|
return ts;
|
||||||
@ -78,6 +79,7 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch)
|
|||||||
struct stksess *ts;
|
struct stksess *ts;
|
||||||
struct eb32_node *eb;
|
struct eb32_node *eb;
|
||||||
int batched = 0;
|
int batched = 0;
|
||||||
|
int looped = 0;
|
||||||
|
|
||||||
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
|
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
|
||||||
|
|
||||||
@ -86,8 +88,12 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch)
|
|||||||
if (unlikely(!eb)) {
|
if (unlikely(!eb)) {
|
||||||
/* we might have reached the end of the tree, typically because
|
/* we might have reached the end of the tree, typically because
|
||||||
* <now_ms> is in the first half and we're first scanning the last
|
* <now_ms> is in the first half and we're first scanning the last
|
||||||
* half. Let's loop back to the beginning of the tree now.
|
* half. Let's loop back to the beginning of the tree now if we
|
||||||
|
* have not yet visited it.
|
||||||
*/
|
*/
|
||||||
|
if (looped)
|
||||||
|
break;
|
||||||
|
looped = 1;
|
||||||
eb = eb32_first(&t->exps);
|
eb = eb32_first(&t->exps);
|
||||||
if (likely(!eb))
|
if (likely(!eb))
|
||||||
break;
|
break;
|
||||||
@ -97,6 +103,10 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch)
|
|||||||
ts = eb32_entry(eb, struct stksess, exp);
|
ts = eb32_entry(eb, struct stksess, exp);
|
||||||
eb = eb32_next(eb);
|
eb = eb32_next(eb);
|
||||||
|
|
||||||
|
/* don't delete an entry which is currently referenced */
|
||||||
|
if (ts->ref_cnt)
|
||||||
|
continue;
|
||||||
|
|
||||||
eb32_delete(&ts->exp);
|
eb32_delete(&ts->exp);
|
||||||
|
|
||||||
if (ts->expire != ts->exp.key) {
|
if (ts->expire != ts->exp.key) {
|
||||||
@ -223,6 +233,7 @@ static int stktable_trash_expired(struct stktable *t)
|
|||||||
{
|
{
|
||||||
struct stksess *ts;
|
struct stksess *ts;
|
||||||
struct eb32_node *eb;
|
struct eb32_node *eb;
|
||||||
|
int looped = 0;
|
||||||
|
|
||||||
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
|
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
|
||||||
|
|
||||||
@ -230,8 +241,12 @@ static int stktable_trash_expired(struct stktable *t)
|
|||||||
if (unlikely(!eb)) {
|
if (unlikely(!eb)) {
|
||||||
/* we might have reached the end of the tree, typically because
|
/* we might have reached the end of the tree, typically because
|
||||||
* <now_ms> is in the first half and we're first scanning the last
|
* <now_ms> is in the first half and we're first scanning the last
|
||||||
* half. Let's loop back to the beginning of the tree now.
|
* half. Let's loop back to the beginning of the tree now if we
|
||||||
|
* have not yet visited it.
|
||||||
*/
|
*/
|
||||||
|
if (looped)
|
||||||
|
break;
|
||||||
|
looped = 1;
|
||||||
eb = eb32_first(&t->exps);
|
eb = eb32_first(&t->exps);
|
||||||
if (likely(!eb))
|
if (likely(!eb))
|
||||||
break;
|
break;
|
||||||
@ -247,6 +262,10 @@ static int stktable_trash_expired(struct stktable *t)
|
|||||||
ts = eb32_entry(eb, struct stksess, exp);
|
ts = eb32_entry(eb, struct stksess, exp);
|
||||||
eb = eb32_next(eb);
|
eb = eb32_next(eb);
|
||||||
|
|
||||||
|
/* don't delete an entry which is currently referenced */
|
||||||
|
if (ts->ref_cnt)
|
||||||
|
continue;
|
||||||
|
|
||||||
eb32_delete(&ts->exp);
|
eb32_delete(&ts->exp);
|
||||||
|
|
||||||
if (!tick_is_expired(ts->expire, now_ms)) {
|
if (!tick_is_expired(ts->expire, now_ms)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user