This function gets called every time Redis is entering the * main loop of the event driven library, that is, before to sleep * for ready file descriptors. * * Note: This function is (currently) called from two functions: * 1. aeMain - The main server loop * 2. processEventsWhileBlocked - Process clients during RDB/AOF load * * If it was called from processEventsWhileBlocked we don't want
| 2835 | * The most important is freeClientsInAsyncFreeQueue but we also |
| 2836 | * call some other low-risk functions. */ |
| 2837 | void beforeSleep(struct aeEventLoop *eventLoop) { |
| 2838 | AeLocker locker; |
| 2839 | int iel = ielFromEventLoop(eventLoop); |
| 2840 | |
| 2841 | tlsProcessPendingData(); |
| 2842 | |
| 2843 | locker.arm(); |
| 2844 | |
| 2845 | /* end any snapshots created by fast async commands */ |
| 2846 | for (int idb = 0; idb < cserver.dbnum; ++idb) { |
| 2847 | if (serverTL->rgdbSnapshot[idb] != nullptr && serverTL->rgdbSnapshot[idb]->FStale()) { |
| 2848 | g_pserver->db[idb]->endSnapshot(serverTL->rgdbSnapshot[idb]); |
| 2849 | serverTL->rgdbSnapshot[idb] = nullptr; |
| 2850 | } |
| 2851 | } |
| 2852 | |
| 2853 | size_t zmalloc_used = zmalloc_used_memory(); |
| 2854 | if (zmalloc_used > g_pserver->stat_peak_memory) |
| 2855 | g_pserver->stat_peak_memory = zmalloc_used; |
| 2856 | |
| 2857 | serverAssert(g_pserver->repl_batch_offStart < 0); |
| 2858 | |
| 2859 | runAndPropogateToReplicas(processClients); |
| 2860 | |
| 2861 | /* Just call a subset of vital functions in case we are re-entering |
| 2862 | * the event loop from processEventsWhileBlocked(). Note that in this |
| 2863 | * case we keep track of the number of events we are processing, since |
| 2864 | * processEventsWhileBlocked() wants to stop ASAP if there are no longer |
| 2865 | * events to handle. */ |
| 2866 | if (ProcessingEventsWhileBlocked) { |
| 2867 | uint64_t processed = 0; |
| 2868 | int aof_state = g_pserver->aof_state; |
| 2869 | locker.disarm(); |
| 2870 | processed += handleClientsWithPendingWrites(iel, aof_state); |
| 2871 | locker.arm(); |
| 2872 | processed += freeClientsInAsyncFreeQueue(iel); |
| 2873 | g_pserver->events_processed_while_blocked += processed; |
| 2874 | return; |
| 2875 | } |
| 2876 | |
| 2877 | /* Handle precise timeouts of blocked clients. */ |
| 2878 | handleBlockedClientsTimeout(); |
| 2879 | |
| 2880 | /* If tls still has pending unread data don't sleep at all. */ |
| 2881 | aeSetDontWait(eventLoop, tlsHasPendingData()); |
| 2882 | |
| 2883 | /* Call the Redis Cluster before sleep function. Note that this function |
| 2884 | * may change the state of Redis Cluster (from ok to fail or vice versa), |
| 2885 | * so it's a good idea to call it before serving the unblocked clients |
| 2886 | * later in this function. */ |
| 2887 | if (g_pserver->cluster_enabled) clusterBeforeSleep(); |
| 2888 | |
| 2889 | /* Run a fast expire cycle (the called function will return |
| 2890 | * ASAP if a fast cycle is not needed). */ |
| 2891 | if (g_pserver->active_expire_enabled && (listLength(g_pserver->masters) == 0 || g_pserver->fActiveReplica)) |
| 2892 | activeExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST); |
| 2893 | |
| 2894 | /* Unblock all the clients blocked for synchronous replication |
nothing calls this directly
no test coverage detected