Fix bug with module GIL being released prematurely (#8061)

This is hopefully usually harmles.
The server.ready_keys will usually be empty so the code after releasing
the GIL will soon be done.
The only case where it'll actually process things is when a module
releases a client (or module) blocked on a key, by triggering this NOT
from within a command (e.g. a timer event).

This bug was introduced in redis 6.0.9, see #7903

(cherry picked from commit e6fa47380a5274119ed37c7a5ea7455d4b7dbdcc)
This commit is contained in:
Oran Agra 2020-11-22 14:00:51 +02:00
parent 3ac666b3e6
commit f885e364ba

View File

@ -2199,15 +2199,17 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
/* Close clients that need to be closed asynchronous */
freeClientsInAsyncFreeQueue();
/* Try to process blocked clients every once in while. Example: A module
* calls RM_SignalKeyAsReady from within a timer callback (So we don't
* visit processCommand() at all). */
handleClientsBlockedOnKeys();
/* Before we are going to sleep, let the threads access the dataset by
* releasing the GIL. Redis main thread will not touch anything at this
* time. */
if (moduleCount()) moduleReleaseGIL();
/* Try to process blocked clients every once in while. Example: A module
* calls RM_SignalKeyAsReady from within a timer callback (So we don't
* visit processCommand() at all). */
handleClientsBlockedOnKeys();
/* Do NOT add anything below moduleReleaseGIL !!! */
}
/* This function is called immediately after the event loop multiplexing
@ -2216,6 +2218,9 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
void afterSleep(struct aeEventLoop *eventLoop) {
UNUSED(eventLoop);
/* Do NOT add anything above moduleAcquireGIL !!! */
/* Aquire the modules GIL so that their threads won't touch anything. */
if (!ProcessingEventsWhileBlocked) {
if (moduleCount()) moduleAcquireGIL();
}