mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-12-03 00:31:00 +01:00
EXP: peers: Use try-lock operations when looping on the updates list
This commit is contained in:
parent
e29863934e
commit
c37b14a705
114
src/peers.c
114
src/peers.c
@ -1549,7 +1549,6 @@ int peer_send_teachmsgs(struct appctx *appctx, struct peer *p, struct shared_tab
|
|||||||
int ret, new_pushed, use_timed;
|
int ret, new_pushed, use_timed;
|
||||||
int updates_sent = 0;
|
int updates_sent = 0;
|
||||||
struct stksess *ts = NULL;
|
struct stksess *ts = NULL;
|
||||||
struct mt_list back;
|
|
||||||
|
|
||||||
TRACE_ENTER(PEERS_EV_SESS_IO, appctx, p, st);
|
TRACE_ENTER(PEERS_EV_SESS_IO, appctx, p, st);
|
||||||
|
|
||||||
@ -1562,79 +1561,69 @@ int peer_send_teachmsgs(struct appctx *appctx, struct peer *p, struct shared_tab
|
|||||||
/* We force new pushed to 1 to force identifier in update message */
|
/* We force new pushed to 1 to force identifier in update message */
|
||||||
new_pushed = 1;
|
new_pushed = 1;
|
||||||
|
|
||||||
MT_LIST_FOR_EACH_ENTRY_LOCKED(ts, &st->last->upd, upd, back) {
|
while (1) {
|
||||||
if (ts == st->end) {
|
struct mt_list el1, el2;
|
||||||
ret = 1; // done
|
|
||||||
|
if (st->last->upd.next == &st->end->upd || st->last->upd.next == &st->table->updates)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (buffer_almost_full(&appctx->outbuf)) {
|
||||||
|
applet_have_more_data(appctx);
|
||||||
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(p->flags & PEER_F_TEACH_PROCESS) && ts->updt_type != STKSESS_UPDT_LOCAL)
|
if (updates_sent >= peers_max_updates_at_once) {
|
||||||
continue;
|
applet_have_more_data(appctx);
|
||||||
else if (ts->updt_type != STKSESS_UPDT_LOCAL && ts->updt_type != STKSESS_UPDT_REMOTE)
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
el1 = mt_list_try_lock_full(&st->last->upd);
|
||||||
|
if (el1.prev == NULL) {
|
||||||
|
applet_have_more_data(appctx);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
el2 = mt_list_lock_next(el1.next);
|
||||||
|
/* el2 = mt_list_try_lock_next(el1.next); */
|
||||||
|
/* if (el2.next == NULL) { */
|
||||||
|
/* mt_list_unlock_full(&st->last->upd, el1); */
|
||||||
|
/* applet_have_more_data(appctx); */
|
||||||
|
/* ret = -1; */
|
||||||
|
/* break; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
ts = MT_LIST_ELEM(el1.next, typeof(ts), upd);
|
||||||
|
HA_ATOMIC_INC(&ts->ref_cnt);
|
||||||
|
|
||||||
|
mt_list_unlock_full(&st->last->upd, el2);
|
||||||
|
mt_list_unlock_link(el1);
|
||||||
|
|
||||||
|
if ((!(p->flags & PEER_F_TEACH_PROCESS) && ts->updt_type != STKSESS_UPDT_LOCAL) ||
|
||||||
|
(ts->updt_type != STKSESS_UPDT_LOCAL && ts->updt_type != STKSESS_UPDT_REMOTE) ||
|
||||||
|
(p->srv->shard && ts->shard != p->srv->shard) ||
|
||||||
|
ts->updt_type == STKSESS_UPDT_MARKER) {
|
||||||
|
HA_ATOMIC_DEC(&ts->ref_cnt);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (st != p->last_local_table) {
|
if (st != p->last_local_table) {
|
||||||
ret = peer_send_switchmsg(st, appctx);
|
ret = peer_send_switchmsg(st, appctx);
|
||||||
if (ret <= 0)
|
if (ret <= 0) {
|
||||||
|
HA_ATOMIC_DEC(&ts->ref_cnt);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
p->last_local_table = st;
|
p->last_local_table = st;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_HA_ATOMIC_LOAD(&ts->seen))
|
if (!_HA_ATOMIC_LOAD(&ts->seen))
|
||||||
_HA_ATOMIC_STORE(&ts->seen, 1);
|
_HA_ATOMIC_STORE(&ts->seen, 1);
|
||||||
|
|
||||||
if (p->srv->shard && ts->shard != p->srv->shard)
|
ret = peer_send_updatemsg(st, appctx, ts, st->update_id, new_pushed, use_timed);
|
||||||
continue;
|
HA_ATOMIC_DEC(&ts->ref_cnt);
|
||||||
|
if (ret <= 0)
|
||||||
if (updates_sent >= peers_max_updates_at_once) {
|
|
||||||
applet_have_more_data(appctx);
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
HA_ATOMIC_INC(&ts->ref_cnt);
|
|
||||||
ret = peer_send_updatemsg(st, appctx, ts, st->update_id, new_pushed, use_timed);
|
|
||||||
HA_ATOMIC_DEC(&ts->ref_cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret <= 0) {
|
|
||||||
/* Insert <last> marker before <ts> to process it again
|
|
||||||
* on next iteration. <ts> remains locked
|
|
||||||
*
|
|
||||||
* Before:
|
|
||||||
* <back>: <A> <==============> <C>
|
|
||||||
*
|
|
||||||
* <last> <==> ... <A> <==> x x <==> <C> ...
|
|
||||||
*
|
|
||||||
* x <==> TS <==> x
|
|
||||||
*
|
|
||||||
* <back>.prev == <A> and <back>.prev->next == MT_LIST_BUSY
|
|
||||||
*
|
|
||||||
* Step 1: detach <last> from the list
|
|
||||||
* Step 2: insert <last> after <A>
|
|
||||||
* - <last>.prev = <A> (or <back>.prev)
|
|
||||||
* - <last>.next = MT_LIST_BUSY (or <back>.prev->next)
|
|
||||||
* Step 3: move <A> before <last>
|
|
||||||
* - <A>.next = <last> (or back.prev->next = <last>)
|
|
||||||
*
|
|
||||||
* Step 4: update <back>.prev to point on <last>
|
|
||||||
*
|
|
||||||
* After:
|
|
||||||
* <back>: <last> <==============> <C>
|
|
||||||
*
|
|
||||||
* ... <A> <==> <last> <==> x x <==> <C> ...
|
|
||||||
*
|
|
||||||
* x <==> TS <==> x
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MT_LIST_DELETE(&st->last->upd);
|
|
||||||
st->last->upd.next = back.prev->next; /* == MT_LIST_BUSY */
|
|
||||||
__ha_barrier_atomic_store();
|
|
||||||
st->last->upd.prev = back.prev;
|
|
||||||
back.prev->next = &st->last->upd;
|
|
||||||
back.prev = &st->last->upd;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
p->last.table = st;
|
p->last.table = st;
|
||||||
p->last.id = st->update_id;
|
p->last.id = st->update_id;
|
||||||
@ -1647,12 +1636,9 @@ int peer_send_teachmsgs(struct appctx *appctx, struct peer *p, struct shared_tab
|
|||||||
updates_sent++;
|
updates_sent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 1) {
|
if (ret == 1)
|
||||||
MT_LIST_DELETE(&st->last->upd);
|
|
||||||
MT_LIST_APPEND(&st->end->upd, &st->last->upd);
|
|
||||||
MT_LIST_DELETE(&st->end->upd);
|
MT_LIST_DELETE(&st->end->upd);
|
||||||
}
|
end:
|
||||||
|
|
||||||
TRACE_LEAVE(PEERS_EV_SESS_IO, appctx, p, st);
|
TRACE_LEAVE(PEERS_EV_SESS_IO, appctx, p, st);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user