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
This commit is contained in:
John Sully 2020-04-15 22:30:19 -04:00
parent 32b028b9cb
commit 822f64ed2f
3 changed files with 9 additions and 6 deletions

View File

@ -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<fastlock> 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;
}

View File

@ -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 */

View File

@ -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);