diff options
author | dormando <dormando@rydia.net> | 2022-12-07 12:14:05 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2022-12-07 12:14:05 -0800 |
commit | 23ca8a0714273c650df0cb6e9034fc804553baab (patch) | |
tree | 67c1d1ab5e862af5b36a8ea8a56aeb3e1727968c /proxy_network.c | |
parent | 146c6489fccf659bbb98e5012169661e7dfc7b69 (diff) | |
download | memcached-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.c | 11 |
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; } |