This function is called every time we are going to transmit new data * to the client. The behavior is the following: * * If the client should receive new data (normal clients will) the function * returns C_OK, and make sure to install the write handler in our event * loop so that when the socket is writable new data gets written. * * If the client should not receive new data, because it is
| 293 | * data to the clients output buffers. If the function returns C_ERR no |
| 294 | * data should be appended to the output buffers. */ |
| 295 | int prepareClientToWrite(client *c) { |
| 296 | bool fAsync = !FCorrectThread(c); // Not async if we're on the right thread |
| 297 | |
| 298 | if (!fAsync) { |
| 299 | serverAssert(c->conn == nullptr || c->lock.fOwnLock()); |
| 300 | } else { |
| 301 | serverAssert(GlobalLocksAcquired()); |
| 302 | } |
| 303 | |
| 304 | auto flags = c->flags.load(std::memory_order_relaxed); |
| 305 | |
| 306 | if (flags & CLIENT_FORCE_REPLY) return C_OK; // FORCE REPLY means we're doing something else with the buffer. |
| 307 | // do not install a write handler |
| 308 | |
| 309 | /* If it's the Lua client we always return ok without installing any |
| 310 | * handler since there is no socket at all. */ |
| 311 | if (flags & (CLIENT_LUA|CLIENT_MODULE)) return C_OK; |
| 312 | |
| 313 | /* If CLIENT_CLOSE_ASAP flag is set, we need not write anything. */ |
| 314 | if (c->flags & CLIENT_CLOSE_ASAP) return C_ERR; |
| 315 | |
| 316 | /* CLIENT REPLY OFF / SKIP handling: don't send replies. */ |
| 317 | if (flags & (CLIENT_REPLY_OFF|CLIENT_REPLY_SKIP)) return C_ERR; |
| 318 | |
| 319 | /* Masters don't receive replies, unless CLIENT_MASTER_FORCE_REPLY flag |
| 320 | * is set. */ |
| 321 | if ((flags & CLIENT_MASTER) && |
| 322 | !(flags & CLIENT_MASTER_FORCE_REPLY)) return C_ERR; |
| 323 | |
| 324 | if (!c->conn) return C_ERR; /* Fake client for AOF loading. */ |
| 325 | |
| 326 | /* Schedule the client to write the output buffers to the socket, unless |
| 327 | * it should already be setup to do so (it has already pending data). */ |
| 328 | if (!fAsync && (c->flags & CLIENT_SLAVE || !clientHasPendingReplies(c))) clientInstallWriteHandler(c); |
| 329 | if (fAsync && !(c->fPendingAsyncWrite)) clientInstallAsyncWriteHandler(c); |
| 330 | |
| 331 | /* Authorize the caller to queue in the output buffer of this client. */ |
| 332 | return C_OK; |
| 333 | } |
| 334 | |
| 335 | /* ----------------------------------------------------------------------------- |
| 336 | * Low level functions to add more data to output buffers. |
no test coverage detected