Skip to content

Commit 3336de9

Browse files
authored
Merge pull request #1 from ADovgalyuk/agent/fix-cached-master-lifecycle
Fix cached master ownership lifecycle
2 parents c5d81d9 + bd66576 commit 3336de9

1 file changed

Lines changed: 15 additions & 16 deletions

File tree

src/replication.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,11 +2342,9 @@ void replicationEmptyDbCallback(void *privdata) {
23422342
* at g_pserver->master, starting from the specified file descriptor. */
23432343
void replicationCreateMasterClient(redisMaster *mi, connection *conn, int dbid) {
23442344
serverAssert(mi->master == nullptr);
2345+
replicationDiscardCachedMaster(mi);
2346+
serverAssert(mi->cached_master == nullptr);
23452347
mi->master = createClient(conn, serverTL - g_pserver->rgthreadvar);
2346-
if (mi->cached_master != nullptr) {
2347-
freeClientAsync(mi->cached_master);
2348-
mi->cached_master = nullptr;
2349-
}
23502348
if (conn)
23512349
{
23522350
serverAssert(connGetPrivateData(mi->master->conn) == mi->master);
@@ -4391,11 +4389,9 @@ void replicationCacheMasterUsingMyself(redisMaster *mi) {
43914389
"to synthesize a cached master: I may be able to synchronize with "
43924390
"the new master with just a partial transfer.");
43934391

4394-
if (mi->cached_master != nullptr)
4395-
{
4396-
// This can happen on first load of the RDB, the master we created in config load is stale
4397-
freeClient(mi->cached_master);
4398-
}
4392+
/* This can happen on first load of the RDB, when the master
4393+
* created during config loading is stale. */
4394+
replicationDiscardCachedMaster(mi);
43994395

44004396
/* This will be used to populate the field g_pserver->master->reploff
44014397
* by replicationCreateMasterClient(). We'll later set the created
@@ -4422,9 +4418,7 @@ void replicationCacheMasterUsingMyself(redisMaster *mi) {
44224418
*
44234419
* Assumes that the passed struct contains valid master info. */
44244420
void replicationCacheMasterUsingMaster(redisMaster *mi) {
4425-
if (mi->cached_master) {
4426-
freeClient(mi->cached_master);
4427-
}
4421+
replicationDiscardCachedMaster(mi);
44284422

44294423
replicationCreateMasterClient(mi, NULL, -1);
44304424
std::lock_guard<decltype(mi->master->lock)> lock(mi->master->lock);
@@ -4440,12 +4434,17 @@ void replicationCacheMasterUsingMaster(redisMaster *mi) {
44404434
/* Free a cached master, called when there are no longer the conditions for
44414435
* a partial resync on reconnection. */
44424436
void replicationDiscardCachedMaster(redisMaster *mi) {
4443-
if (mi->cached_master == NULL) return;
4437+
client *cached = mi->cached_master;
4438+
if (cached == nullptr) return;
44444439

44454440
serverLog(LL_NOTICE,"Discarding previously cached master state.");
4446-
mi->cached_master->flags &= ~CLIENT_MASTER;
4447-
freeClientAsync(mi->cached_master);
4448-
mi->cached_master = NULL;
4441+
4442+
/* Transfer ownership before scheduling the client for asynchronous free.
4443+
* No later replication transition may observe the queued client through
4444+
* mi->cached_master. */
4445+
mi->cached_master = nullptr;
4446+
cached->flags &= ~CLIENT_MASTER;
4447+
freeClientAsync(cached);
44494448
}
44504449

44514450
/* Turn the cached master into the current master, using the file descriptor

0 commit comments

Comments
 (0)