From 822f64ed2f29b155775967f9bc06ea2190158f3b Mon Sep 17 00:00:00 2001 From: John Sully Date: Wed, 15 Apr 2020 22:30:19 -0400 Subject: [PATCH] During AOF reload we can erroneously read incorrect aof_state values, so this variable must be read with the global lock acquired Former-commit-id: 6ff9d23fd4541a011d754209d9fda3ef3af4a7f9 --- src/networking.cpp | 7 ++++--- src/server.cpp | 6 ++++-- src/server.h | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/networking.cpp b/src/networking.cpp index c8473b89a..1cb9eade6 100644 --- a/src/networking.cpp +++ b/src/networking.cpp @@ -1856,7 +1856,7 @@ void ProcessPendingAsyncWrites() * we can just write the replies to the client output buffer without any * need to use a syscall in order to install the writable event handler, * get it called, and so forth. */ -int handleClientsWithPendingWrites(int iel) { +int handleClientsWithPendingWrites(int iel, int aof_state) { std::unique_lock lockf(g_pserver->rgthreadvar[iel].lockPendingWrite); auto &vec = g_pserver->rgthreadvar[iel].clients_pending_write; int processed = (int)vec.size(); @@ -1868,7 +1868,7 @@ int handleClientsWithPendingWrites(int iel) { * so that in the middle of receiving the query, and serving it * to the client, we'll call beforeSleep() that will do the * actual fsync of AOF to disk. AE_BARRIER ensures that. */ - if (g_pserver->aof_state == AOF_ON && + if (aof_state == AOF_ON && g_pserver->aof_fsync == AOF_FSYNC_ALWAYS) { ae_flags |= AE_BARRIER; @@ -3359,6 +3359,7 @@ int processEventsWhileBlocked(int iel) { } + int aof_state = g_pserver->aof_state; aeReleaseLock(); serverAssertDebug(!GlobalLocksAcquired()); try @@ -3366,7 +3367,7 @@ int processEventsWhileBlocked(int iel) { while (iterations--) { int events = 0; events += aeProcessEvents(g_pserver->rgthreadvar[iel].el, AE_FILE_EVENTS|AE_DONT_WAIT); - events += handleClientsWithPendingWrites(iel); + events += handleClientsWithPendingWrites(iel, aof_state); if (!events) break; count += events; } diff --git a/src/server.cpp b/src/server.cpp index f080adf2b..1ebf71b1e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2191,8 +2191,9 @@ void beforeSleep(struct aeEventLoop *eventLoop) { flushAppendOnlyFile(0); /* Handle writes with pending output buffers. */ + int aof_state = g_pserver->aof_state; aeReleaseLock(); - handleClientsWithPendingWrites(IDX_EVENT_LOOP_MAIN); + handleClientsWithPendingWrites(IDX_EVENT_LOOP_MAIN, aof_state); aeAcquireLock(); /* Close clients that need to be closed asynchronous */ @@ -2217,10 +2218,11 @@ void beforeSleepLite(struct aeEventLoop *eventLoop) /* Check if there are clients unblocked by modules that implement * blocking commands. */ if (moduleCount()) moduleHandleBlockedClients(ielFromEventLoop(eventLoop)); + int aof_state = g_pserver->aof_state; aeReleaseLock(); /* Handle writes with pending output buffers. */ - handleClientsWithPendingWrites(iel); + handleClientsWithPendingWrites(iel, aof_state); aeAcquireLock(); /* Close clients that need to be closed asynchronous */ diff --git a/src/server.h b/src/server.h index 10941adfc..3a08b4d6a 100644 --- a/src/server.h +++ b/src/server.h @@ -2203,7 +2203,7 @@ void pauseClients(mstime_t duration); int clientsArePaused(void); void unpauseClientsIfNecessary(); int processEventsWhileBlocked(int iel); -int handleClientsWithPendingWrites(int iel); +int handleClientsWithPendingWrites(int iel, int aof_state); int clientHasPendingReplies(client *c); void unlinkClient(client *c); int writeToClient(client *c, int handler_installed);