Skip to content
Snippets Groups Projects
Commit 05f7ff7c authored by Serge Petrenko's avatar Serge Petrenko Committed by Kirill Yukhin
Browse files

box: add a single execution guard to clear_synchro_queue

Clear_synchro_queue isn't meant to be called multiple times on a single
instance.

Multiple simultaneous invocations of clear_synhcro_queue() shouldn't
hurt now, since clear_synchro_queue simply exits on an empty limbo, but
may be harmful in future, when clear_synchro_queue is reworked.

Prohibit such misuse by introducing an execution guard and raising an
error once duplicate invocation is detected.

Prerequisite #5435
parent cdb5f603
No related branches found
No related tags found
No related merge requests found
......@@ -1135,15 +1135,24 @@ box_set_replication_anon(void)
}
void
int
box_clear_synchro_queue(bool try_wait)
{
/* A guard to block multiple simultaneous function invocations. */
static bool in_clear_synchro_queue = false;
if (in_clear_synchro_queue) {
diag_set(ClientError, ER_UNSUPPORTED, "clear_synchro_queue",
"simultaneous invocations");
return -1;
}
if (!is_box_configured || txn_limbo_is_empty(&txn_limbo))
return;
return 0;
uint32_t former_leader_id = txn_limbo.owner_id;
assert(former_leader_id != REPLICA_ID_NIL);
if (former_leader_id == instance_id)
return;
return 0;
in_clear_synchro_queue = true;
if (try_wait) {
/* Wait until pending confirmations/rollbacks reach us. */
......@@ -1184,6 +1193,9 @@ box_clear_synchro_queue(bool try_wait)
txn_limbo_force_empty(&txn_limbo, confirm_lsn);
assert(txn_limbo_is_empty(&txn_limbo));
}
in_clear_synchro_queue = false;
return 0;
}
void
......
......@@ -268,7 +268,7 @@ extern "C" {
typedef struct tuple box_tuple_t;
void
int
box_clear_synchro_queue(bool try_wait);
/* box_select is private and used only by FFI */
......
......@@ -83,8 +83,8 @@ lbox_ctl_on_schema_init(struct lua_State *L)
static int
lbox_ctl_clear_synchro_queue(struct lua_State *L)
{
(void) L;
box_clear_synchro_queue(true);
if (box_clear_synchro_queue(true) != 0)
return luaT_error(L);
return 0;
}
......
......@@ -89,9 +89,14 @@ box_raft_update_synchro_queue(struct raft *raft)
* If the node became a leader, it means it will ignore all records from
* all the other nodes, and won't get late CONFIRM messages anyway. Can
* clear the queue without waiting for confirmations.
* It's alright that the user may have called clear_synchro_queue
* manually. In this case the call below will exit immediately and we'll
* simply log a warning.
*/
if (raft->state == RAFT_STATE_LEADER)
box_clear_synchro_queue(false);
if (raft->state == RAFT_STATE_LEADER) {
if (box_clear_synchro_queue(false) != 0)
diag_log();
}
}
static int
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment