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
This commit is contained in:
parent
61954951ed
commit
e6fa47380a
13
src/server.c
13
src/server.c
@ -2306,15 +2306,17 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
/* Close clients that need to be closed asynchronous */
|
/* Close clients that need to be closed asynchronous */
|
||||||
freeClientsInAsyncFreeQueue();
|
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
|
/* 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
|
* releasing the GIL. Redis main thread will not touch anything at this
|
||||||
* time. */
|
* time. */
|
||||||
if (moduleCount()) moduleReleaseGIL();
|
if (moduleCount()) moduleReleaseGIL();
|
||||||
|
|
||||||
/* Try to process blocked clients every once in while. Example: A module
|
/* Do NOT add anything below moduleReleaseGIL !!! */
|
||||||
* calls RM_SignalKeyAsReady from within a timer callback (So we don't
|
|
||||||
* visit processCommand() at all). */
|
|
||||||
handleClientsBlockedOnKeys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called immediately after the event loop multiplexing
|
/* This function is called immediately after the event loop multiplexing
|
||||||
@ -2323,6 +2325,9 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
void afterSleep(struct aeEventLoop *eventLoop) {
|
void afterSleep(struct aeEventLoop *eventLoop) {
|
||||||
UNUSED(eventLoop);
|
UNUSED(eventLoop);
|
||||||
|
|
||||||
|
/* Do NOT add anything above moduleAcquireGIL !!! */
|
||||||
|
|
||||||
|
/* Aquire the modules GIL so that their threads won't touch anything. */
|
||||||
if (!ProcessingEventsWhileBlocked) {
|
if (!ProcessingEventsWhileBlocked) {
|
||||||
if (moduleCount()) moduleAcquireGIL();
|
if (moduleCount()) moduleAcquireGIL();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user