MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / handleClientsWithPendingWrites

Function handleClientsWithPendingWrites

src/networking.cpp:2067–2130  ·  view source on GitHub ↗

This function is called just before entering the event loop, in the hope * we can just write the replies to the client output buffer without any * need to use a syscall in order to install the writable event handler, * get it called, and so forth. */

Source from the content-addressed store, hash-verified

2065 * need to use a syscall in order to install the writable event handler,
2066 * get it called, and so forth. */
2067int handleClientsWithPendingWrites(int iel, int aof_state) {
2068 int processed = 0;
2069 serverAssert(iel == (serverTL - g_pserver->rgthreadvar));
2070
2071 if (listLength(serverTL->clients_pending_asyncwrite))
2072 {
2073 AeLocker locker;
2074 locker.arm(nullptr);
2075 ProcessPendingAsyncWrites();
2076 }
2077
2078 int ae_flags = AE_WRITABLE|AE_WRITE_THREADSAFE;
2079 /* For the fsync=always policy, we want that a given FD is never
2080 * served for reading and writing in the same event loop iteration,
2081 * so that in the middle of receiving the query, and serving it
2082 * to the client, we'll call beforeSleep() that will do the
2083 * actual fsync of AOF to disk. AE_BARRIER ensures that. */
2084 if (aof_state == AOF_ON &&
2085 g_pserver->aof_fsync == AOF_FSYNC_ALWAYS)
2086 {
2087 ae_flags |= AE_BARRIER;
2088 }
2089
2090 std::unique_lock<fastlock> lockf(g_pserver->rgthreadvar[iel].lockPendingWrite);
2091 auto vec = std::move(g_pserver->rgthreadvar[iel].clients_pending_write);
2092 lockf.unlock();
2093 processed += (int)vec.size();
2094
2095 for (client *c : vec) {
2096 serverAssertDebug(FCorrectThread(c));
2097
2098 uint64_t flags = c->flags.fetch_and(~CLIENT_PENDING_WRITE, std::memory_order_relaxed);
2099
2100 /* If a client is protected, don't do anything,
2101 * that may trigger write error or recreate handler. */
2102 if ((flags & CLIENT_PROTECTED) && !(flags & CLIENT_SLAVE)) continue;
2103
2104 /* Don't write to clients that are going to be closed anyway. */
2105 if (c->flags & CLIENT_CLOSE_ASAP) continue;
2106
2107 /* Try to write buffers to the client socket, unless its a replica in multithread mode */
2108 if (writeToClient(c,0) == C_ERR)
2109 {
2110 if (c->flags & CLIENT_CLOSE_ASAP)
2111 {
2112 AeLocker ae;
2113 ae.arm(nullptr);
2114 freeClient(c); // writeToClient will only async close, but there's no need to wait
2115 }
2116 continue;
2117 }
2118
2119 /* If after the synchronous writes above we still have data to
2120 * output to the client, we need to install the writable handler. */
2121 std::unique_lock<decltype(c->lock)> lock(c->lock);
2122 if (clientHasPendingReplies(c)) {
2123 if (connSetWriteHandlerWithBarrier(c->conn, sendReplyToClient, ae_flags, true) == C_ERR) {
2124 freeClientAsync(c);

Callers 2

beforeSleepFunction · 0.85

Calls 10

FCorrectThreadFunction · 0.85
writeToClientFunction · 0.85
clientHasPendingRepliesFunction · 0.85
freeClientAsyncFunction · 0.85
armMethod · 0.80
freeClientFunction · 0.70
unlockMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected