summaryrefslogtreecommitdiff
path: root/proxy_network.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-12-07 12:14:05 -0800
committerdormando <dormando@rydia.net>2022-12-07 12:14:05 -0800
commit23ca8a0714273c650df0cb6e9034fc804553baab (patch)
tree67c1d1ab5e862af5b36a8ea8a56aeb3e1727968c /proxy_network.c
parent146c6489fccf659bbb98e5012169661e7dfc7b69 (diff)
downloadmemcached-23ca8a0714273c650df0cb6e9034fc804553baab.tar.gz
proxy: crash fix for previous perf fix
There's at least one obscure code path where the be->io_next was being reset and then immediately flushed, which I found after running a torture test for a while. Decided to just armor the write prep function to seed be->io_next if missing, which has been working without crashing since.
Diffstat (limited to 'proxy_network.c')
-rw-r--r--proxy_network.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/proxy_network.c b/proxy_network.c
index 61fa69b..adebeee 100644
--- a/proxy_network.c
+++ b/proxy_network.c
@@ -88,9 +88,7 @@ static int _proxy_event_handler_dequeue(proxy_event_thread_t *t) {
}
STAILQ_INSERT_TAIL(&be->io_head, io, io_next);
if (be->io_next == NULL) {
- // separate pointer into the request queue for how far we've
- // flushed writes.
- be->io_next = io;
+ be->io_next = io; // set write flush starting point.
}
be->depth++;
io_count++;
@@ -936,8 +934,12 @@ static int _prep_pending_write(mcp_backend_t *be, unsigned int *tosend) {
struct iovec *iovs = be->write_iovs;
io_pending_proxy_t *io = NULL;
int iovused = 0;
- assert(be->io_next != NULL);
+ if (be->io_next == NULL) {
+ // separate pointer for how far into the list we've flushed.
+ be->io_next = STAILQ_FIRST(&be->io_head);
+ }
io = be->io_next;
+ assert(io != NULL);
for (; io; io = STAILQ_NEXT(io, io_next)) {
// TODO (v2): paranoia for now, but this check should never fire
if (io->flushed)
@@ -971,6 +973,7 @@ static int _flush_pending_write(mcp_backend_t *be) {
ssize_t sent = writev(mcmc_fd(be->client), be->write_iovs, iovcnt);
if (sent > 0) {
io_pending_proxy_t *io = be->io_next;
+ assert(io != NULL);
if (sent < tosend) {
flags |= EV_WRITE;
}