| 1981 | } |
| 1982 | |
| 1983 | void ProcessPendingAsyncWrites() |
| 1984 | { |
| 1985 | if (serverTL == nullptr) |
| 1986 | return; // module fake call |
| 1987 | |
| 1988 | serverAssert(GlobalLocksAcquired()); |
| 1989 | |
| 1990 | while(listLength(serverTL->clients_pending_asyncwrite)) { |
| 1991 | client *c = (client*)listNodeValue(listFirst(serverTL->clients_pending_asyncwrite)); |
| 1992 | listDelNode(serverTL->clients_pending_asyncwrite, listFirst(serverTL->clients_pending_asyncwrite)); |
| 1993 | std::lock_guard<decltype(c->lock)> lock(c->lock); |
| 1994 | |
| 1995 | serverAssert(c->fPendingAsyncWrite); |
| 1996 | if (c->flags & (CLIENT_CLOSE_ASAP | CLIENT_CLOSE_AFTER_REPLY)) |
| 1997 | { |
| 1998 | if (c->replyAsync != nullptr){ |
| 1999 | zfree(c->replyAsync); |
| 2000 | c->replyAsync = nullptr; |
| 2001 | } |
| 2002 | c->fPendingAsyncWrite = FALSE; |
| 2003 | continue; |
| 2004 | } |
| 2005 | |
| 2006 | /* since writes from master to replica can come directly from the replication backlog, |
| 2007 | * writes may have been signalled without having been copied to the replyAsync buffer, |
| 2008 | * thus causing the buffer to be NULL */ |
| 2009 | if (c->replyAsync != nullptr){ |
| 2010 | size_t size = c->replyAsync->used; |
| 2011 | |
| 2012 | if (listLength(c->reply) == 0 && size <= static_cast<size_t>(PROTO_REPLY_CHUNK_BYTES - c->bufpos)) { |
| 2013 | memcpy(c->buf + c->bufpos, c->replyAsync->buf(), size); |
| 2014 | c->bufpos += size; |
| 2015 | } else { |
| 2016 | c->reply_bytes += c->replyAsync->size; |
| 2017 | listAddNodeTail(c->reply, c->replyAsync); |
| 2018 | c->replyAsync = nullptr; |
| 2019 | } |
| 2020 | |
| 2021 | zfree(c->replyAsync); |
| 2022 | c->replyAsync = nullptr; |
| 2023 | } else { |
| 2024 | /* Only replicas should have empty async reply buffers */ |
| 2025 | serverAssert(c->flags & CLIENT_SLAVE); |
| 2026 | } |
| 2027 | |
| 2028 | c->fPendingAsyncWrite = FALSE; |
| 2029 | |
| 2030 | if (!((c->replstate == REPL_STATE_NONE || c->replstate == SLAVE_STATE_FASTSYNC_TX || |
| 2031 | (c->replstate == SLAVE_STATE_ONLINE && !c->repl_put_online_on_ack)))) |
| 2032 | continue; |
| 2033 | |
| 2034 | closeClientOnOutputBufferLimitReached(c, 1); |
| 2035 | if (c->flags & CLIENT_CLOSE_ASAP) |
| 2036 | continue; // we will never write this so don't post an op |
| 2037 | |
| 2038 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 2039 | |
| 2040 | if (FCorrectThread(c)) |
no test coverage detected