{
struct eb32_node * eb;
int locked = 0;
+ int old_exp, new_exp;
if (expire != HA_ATOMIC_LOAD(&ts->expire)) {
/* we'll need to set the expiration and to wake up the expiration timer .*/
HA_ATOMIC_STORE(&ts->expire, expire);
if (t->expire) {
- if (!locked++)
- HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
- t->exp_task->expire = t->exp_next = tick_first(expire, t->exp_next);
+ /* set both t->exp_next and the task's expire to the newest
+ * expiration date.
+ */
+ old_exp = HA_ATOMIC_LOAD(&t->exp_next);
+ do {
+ new_exp = tick_first(expire, old_exp);
+ } while (new_exp != old_exp &&
+ !HA_ATOMIC_CAS(&t->exp_next, &old_exp, new_exp) &&
+ __ha_cpu_relax());
+
+ old_exp = HA_ATOMIC_LOAD(&t->exp_task->expire);
+ do {
+ new_exp = HA_ATOMIC_LOAD(&t->exp_next);
+ } while (new_exp != old_exp &&
+ !HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp) &&
+ __ha_cpu_relax());
+
task_queue(t->exp_task);
/* keep the lock */
}