*/
struct stksess {
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 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 */
static struct stksess *stksess_init(struct stktable *t, struct stksess * ts)
{
memset((void *)ts - t->data_size, 0, t->data_size);
+ ts->ref_cnt = 0;
ts->key.node.leaf_p = NULL;
ts->exp.node.leaf_p = NULL;
return ts;
struct stksess *ts;
struct eb32_node *eb;
int batched = 0;
+ int looped = 0;
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
if (unlikely(!eb)) {
/* 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
- * 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);
if (likely(!eb))
break;
ts = eb32_entry(eb, struct stksess, exp);
eb = eb32_next(eb);
+ /* don't delete an entry which is currently referenced */
+ if (ts->ref_cnt)
+ continue;
+
eb32_delete(&ts->exp);
if (ts->expire != ts->exp.key) {
{
struct stksess *ts;
struct eb32_node *eb;
+ int looped = 0;
eb = eb32_lookup_ge(&t->exps, now_ms - TIMER_LOOK_BACK);
if (unlikely(!eb)) {
/* 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
- * 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);
if (likely(!eb))
break;
ts = eb32_entry(eb, struct stksess, exp);
eb = eb32_next(eb);
+ /* don't delete an entry which is currently referenced */
+ if (ts->ref_cnt)
+ continue;
+
eb32_delete(&ts->exp);
if (!tick_is_expired(ts->expire, now_ms)) {