From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 0680346970F for ; Mon, 25 Nov 2019 14:50:13 +0300 (MSK) From: Ilya Kosarev Date: Mon, 25 Nov 2019 14:50:07 +0300 Message-Id: In-Reply-To: References: In-Reply-To: References: Subject: [Tarantool-patches] [PATCH v3 2/4] replication: fix appliers pruning List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org 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 509187cd3..f15e51f4d 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; -- 2.17.1