unsigned int update; /* uses updt_lock */
unsigned int localupdate; /* uses updt_lock */
unsigned int commitupdate;/* used to identify the latest local updates pending for sync, uses updt_lock */
+ __decl_thread(HA_RWLOCK_T updt_lock); /* lock protecting the updates part */
};
extern struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
new_pushed = 1;
if (locked)
- HA_RWLOCK_WRTORD(STK_TABLE_LOCK, &st->table->lock);
- else
- HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &st->table->lock);
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &st->table->lock);
+
+ HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
while (1) {
struct stksess *ts;
}
HA_ATOMIC_INC(&ts->ref_cnt);
- HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &st->table->lock);
+ HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
ret = peer_send_updatemsg(st, appctx, ts, updateid, new_pushed, use_timed);
- HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &st->table->lock);
+ HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
HA_ATOMIC_DEC(&ts->ref_cnt);
if (ret <= 0)
break;
}
out:
- HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &st->table->lock);
+ HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &st->table->updt_lock);
if (locked)
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &st->table->lock);
return 0;
eb32_delete(&ts->exp);
- eb32_delete(&ts->upd);
+ if (ts->upd.node.leaf_p) {
+ HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
+ eb32_delete(&ts->upd);
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
+ }
ebmb_delete(&ts->key);
__stksess_free(t, ts);
return 1;
/* session expired, trash it */
ebmb_delete(&ts->key);
- eb32_delete(&ts->upd);
+ if (ts->upd.node.leaf_p) {
+ HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
+ eb32_delete(&ts->upd);
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
+ }
__stksess_free(t, ts);
batched++;
}
* or not scheduled for at least one peer.
*/
if (!locked++)
- HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
+ HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
if (!ts->upd.node.leaf_p
|| (int)(t->commitupdate - ts->upd.key) >= 0
else {
/* If this entry is not in the tree */
if (!locked++)
- HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
+ HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
if (!ts->upd.node.leaf_p) {
ts->upd.key= (++t->update)+(2147483648U);
}
if (locked)
- HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
if (decrefcnt)
HA_ATOMIC_DEC(&ts->ref_cnt);
struct stktable *t = context;
struct stksess *ts;
struct eb32_node *eb;
+ int updt_locked = 0;
int looped = 0;
int exp_next;
/* session expired, trash it */
ebmb_delete(&ts->key);
- eb32_delete(&ts->upd);
+ if (ts->upd.node.leaf_p) {
+ if (!updt_locked) {
+ updt_locked = 1;
+ HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock);
+ }
+ eb32_delete(&ts->upd);
+ }
__stksess_free(t, ts);
}
out_unlock:
task->expire = exp_next;
+ if (updt_locked)
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock);
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
return task;
}