Some rework of #7234.
This commit is contained in:
parent
9da134cd88
commit
8bf660af90
7
src/ae.c
7
src/ae.c
@ -370,6 +370,7 @@ static int processTimeEvents(aeEventLoop *eventLoop) {
|
|||||||
* if flags has AE_DONT_WAIT set the function returns ASAP until all
|
* if flags has AE_DONT_WAIT set the function returns ASAP until all
|
||||||
* the events that's possible to process without to wait are processed.
|
* the events that's possible to process without to wait are processed.
|
||||||
* if flags has AE_CALL_AFTER_SLEEP set, the aftersleep callback is called.
|
* if flags has AE_CALL_AFTER_SLEEP set, the aftersleep callback is called.
|
||||||
|
* if flags has AE_CALL_BEFORE_SLEEP set, the beforesleep callback is called.
|
||||||
*
|
*
|
||||||
* The function returns the number of events processed. */
|
* The function returns the number of events processed. */
|
||||||
int aeProcessEvents(aeEventLoop *eventLoop, int flags)
|
int aeProcessEvents(aeEventLoop *eventLoop, int flags)
|
||||||
@ -428,7 +429,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags)
|
|||||||
tvp = &tv;
|
tvp = &tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventLoop->beforesleep != NULL)
|
if (eventLoop->beforesleep != NULL && flags & AE_CALL_BEFORE_SLEEP)
|
||||||
eventLoop->beforesleep(eventLoop);
|
eventLoop->beforesleep(eventLoop);
|
||||||
|
|
||||||
/* Call the multiplexing API, will return only on timeout or when
|
/* Call the multiplexing API, will return only on timeout or when
|
||||||
@ -525,7 +526,9 @@ int aeWait(int fd, int mask, long long milliseconds) {
|
|||||||
void aeMain(aeEventLoop *eventLoop) {
|
void aeMain(aeEventLoop *eventLoop) {
|
||||||
eventLoop->stop = 0;
|
eventLoop->stop = 0;
|
||||||
while (!eventLoop->stop) {
|
while (!eventLoop->stop) {
|
||||||
aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
|
aeProcessEvents(eventLoop, AE_ALL_EVENTS|
|
||||||
|
AE_CALL_BEFORE_SLEEP|
|
||||||
|
AE_CALL_AFTER_SLEEP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
src/ae.h
9
src/ae.h
@ -47,11 +47,12 @@
|
|||||||
things to disk before sending replies, and want
|
things to disk before sending replies, and want
|
||||||
to do that in a group fashion. */
|
to do that in a group fashion. */
|
||||||
|
|
||||||
#define AE_FILE_EVENTS 1
|
#define AE_FILE_EVENTS (1<<0)
|
||||||
#define AE_TIME_EVENTS 2
|
#define AE_TIME_EVENTS (1<<1)
|
||||||
#define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS)
|
#define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS)
|
||||||
#define AE_DONT_WAIT 4
|
#define AE_DONT_WAIT (1<<2)
|
||||||
#define AE_CALL_AFTER_SLEEP 8
|
#define AE_CALL_BEFORE_SLEEP (1<<3)
|
||||||
|
#define AE_CALL_AFTER_SLEEP (1<<4)
|
||||||
|
|
||||||
#define AE_NOMORE -1
|
#define AE_NOMORE -1
|
||||||
#define AE_DELETED_EVENT_ID -1
|
#define AE_DELETED_EVENT_ID -1
|
||||||
|
@ -2863,8 +2863,9 @@ int processEventsWhileBlocked(void) {
|
|||||||
ProcessingEventsWhileBlocked = 1;
|
ProcessingEventsWhileBlocked = 1;
|
||||||
while (iterations--) {
|
while (iterations--) {
|
||||||
int events = 0;
|
int events = 0;
|
||||||
events += aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT);
|
events += aeProcessEvents(server.el,
|
||||||
events += handleClientsWithPendingWrites();
|
AE_FILE_EVENTS|AE_DONT_WAIT|
|
||||||
|
AE_CALL_BEFORE_SLEEP|AE_CALL_AFTER_SLEEP);
|
||||||
if (!events) break;
|
if (!events) break;
|
||||||
count += events;
|
count += events;
|
||||||
}
|
}
|
||||||
|
19
src/server.c
19
src/server.c
@ -2092,21 +2092,32 @@ extern int ProcessingEventsWhileBlocked;
|
|||||||
/* This function gets called every time Redis is entering the
|
/* This function gets called every time Redis is entering the
|
||||||
* main loop of the event driven library, that is, before to sleep
|
* main loop of the event driven library, that is, before to sleep
|
||||||
* for ready file descriptors.
|
* for ready file descriptors.
|
||||||
|
*
|
||||||
* Note: This function is (currently) called from two functions:
|
* Note: This function is (currently) called from two functions:
|
||||||
* 1. aeMain - The main server loop
|
* 1. aeMain - The main server loop
|
||||||
* 2. processEventsWhileBlocked - Process clients during RDB/AOF load
|
* 2. processEventsWhileBlocked - Process clients during RDB/AOF load
|
||||||
|
*
|
||||||
* If it was called from processEventsWhileBlocked we don't want
|
* If it was called from processEventsWhileBlocked we don't want
|
||||||
* to perform all actions (For example, we don't want to expire
|
* to perform all actions (For example, we don't want to expire
|
||||||
* keys), but we do need to perform some actions.
|
* keys), but we do need to perform some actions.
|
||||||
|
*
|
||||||
* The most important is freeClientsInAsyncFreeQueue but we also
|
* The most important is freeClientsInAsyncFreeQueue but we also
|
||||||
* call some other low-risk functions. */
|
* call some other low-risk functions. */
|
||||||
void beforeSleep(struct aeEventLoop *eventLoop) {
|
void beforeSleep(struct aeEventLoop *eventLoop) {
|
||||||
UNUSED(eventLoop);
|
UNUSED(eventLoop);
|
||||||
|
|
||||||
if (!ProcessingEventsWhileBlocked) {
|
/* Just call a subset of vital functions in case we are re-entering
|
||||||
|
* the event loop from processEventsWhileBlocked(). */
|
||||||
|
if (ProcessingEventsWhileBlocked) {
|
||||||
|
handleClientsWithPendingReadsUsingThreads();
|
||||||
|
tlsProcessPendingData();
|
||||||
|
handleClientsWithPendingWrites();
|
||||||
|
freeClientsInAsyncFreeQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle precise timeouts of blocked clients. */
|
/* Handle precise timeouts of blocked clients. */
|
||||||
handleBlockedClientsTimeout();
|
handleBlockedClientsTimeout();
|
||||||
}
|
|
||||||
|
|
||||||
/* We should handle pending reads clients ASAP after event loop. */
|
/* We should handle pending reads clients ASAP after event loop. */
|
||||||
handleClientsWithPendingReadsUsingThreads();
|
handleClientsWithPendingReadsUsingThreads();
|
||||||
@ -2117,7 +2128,6 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
/* If tls still has pending unread data don't sleep at all. */
|
/* If tls still has pending unread data don't sleep at all. */
|
||||||
aeSetDontWait(server.el, tlsHasPendingData());
|
aeSetDontWait(server.el, tlsHasPendingData());
|
||||||
|
|
||||||
if (!ProcessingEventsWhileBlocked) {
|
|
||||||
/* Call the Redis Cluster before sleep function. Note that this function
|
/* Call the Redis Cluster before sleep function. Note that this function
|
||||||
* may change the state of Redis Cluster (from ok to fail or vice versa),
|
* may change the state of Redis Cluster (from ok to fail or vice versa),
|
||||||
* so it's a good idea to call it before serving the unblocked clients
|
* so it's a good idea to call it before serving the unblocked clients
|
||||||
@ -2166,7 +2176,6 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
|
|
||||||
/* Write the AOF buffer on disk */
|
/* Write the AOF buffer on disk */
|
||||||
flushAppendOnlyFile(0);
|
flushAppendOnlyFile(0);
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle writes with pending output buffers. */
|
/* Handle writes with pending output buffers. */
|
||||||
handleClientsWithPendingWritesUsingThreads();
|
handleClientsWithPendingWritesUsingThreads();
|
||||||
@ -2174,12 +2183,10 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
/* Close clients that need to be closed asynchronous */
|
/* Close clients that need to be closed asynchronous */
|
||||||
freeClientsInAsyncFreeQueue();
|
freeClientsInAsyncFreeQueue();
|
||||||
|
|
||||||
if (!ProcessingEventsWhileBlocked) {
|
|
||||||
/* 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();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called immadiately after the event loop multiplexing
|
/* This function is called immadiately after the event loop multiplexing
|
||||||
|
Loading…
x
Reference in New Issue
Block a user