Fix crashes with io-threads-do-reads enabled. (#8230)

Normally IO threads should simply read data from the socket into the
buffer and attempt to parse it.

If a protocol error is detected, a reply is generated which may result
with installing a write handler which is not thread safe. This fix
delays that until the client is processed back in the main thread.

Fixes #8220
This commit is contained in:
Yossi Gottlieb 2020-12-22 12:24:20 +02:00 committed by GitHub
parent 411c18bbce
commit e7047ec2fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -259,8 +259,14 @@ int prepareClientToWrite(client *c) {
if (!c->conn) return C_ERR; /* Fake client for AOF loading. */
/* Schedule the client to write the output buffers to the socket, unless
* it should already be setup to do so (it has already pending data). */
if (!clientHasPendingReplies(c)) clientInstallWriteHandler(c);
* it should already be setup to do so (it has already pending data).
*
* If CLIENT_PENDING_READ is set, we're in an IO thread and should
* not install a write handler. Instead, it will be done by
* handleClientsWithPendingReadsUsingThreads() upon return.
*/
if (!clientHasPendingReplies(c) && !(c->flags & CLIENT_PENDING_READ))
clientInstallWriteHandler(c);
/* Authorize the caller to queue in the output buffer of this client. */
return C_OK;
@ -3509,6 +3515,12 @@ int handleClientsWithPendingReadsUsingThreads(void) {
}
}
processInputBuffer(c);
/* We may have pending replies if a thread readQueryFromClient() produced
* replies and did not install a write handler (it can't).
*/
if (!(c->flags & CLIENT_PENDING_WRITE) && clientHasPendingReplies(c))
clientInstallWriteHandler(c);
}
/* Update processed count on server */