From 36ff3c89d02d897b980a8498c68d696c2193c326 Mon Sep 17 00:00:00 2001 From: Ilya Kosarev <i.kosarev@tarantool.org> Date: Mon, 25 Nov 2019 14:24:25 +0300 Subject: [PATCH] replication: fix appliers pruning During pruning of appliers some anon replicas might connect from replicaset_follow called in another fiber. Therefore we need to prune appliers of anon replicas first and, moreover, prune them one by one instead of iterating them, as far as any of them might connect while we are stopping the other one and it will break iteration. Part of #4586 Closes #4643 --- src/box/replication.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/box/replication.cc b/src/box/replication.cc index 509187cd3c..f15e51f4da 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -516,23 +516,25 @@ replicaset_update(struct applier **appliers, int count) */ /* Prune old appliers */ - replicaset_foreach(replica) { - if (replica->applier == NULL) - continue; + while (!rlist_empty(&replicaset.anon)) { + replica = rlist_first_entry(&replicaset.anon, + typeof(*replica), in_anon); applier = replica->applier; replica_clear_applier(replica); - replica->applier_sync_state = APPLIER_DISCONNECTED; + rlist_del_entry(replica, in_anon); + replica_delete(replica); applier_stop(applier); applier_delete(applier); } - rlist_foreach_entry_safe(replica, &replicaset.anon, in_anon, next) { + replicaset_foreach(replica) { + if (replica->applier == NULL) + continue; applier = replica->applier; replica_clear_applier(replica); - replica_delete(replica); + replica->applier_sync_state = APPLIER_DISCONNECTED; applier_stop(applier); applier_delete(applier); } - rlist_create(&replicaset.anon); /* Save new appliers */ replicaset.applier.total = count; -- GitLab