From 23ca8a0714273c650df0cb6e9034fc804553baab Mon Sep 17 00:00:00 2001 From: dormando Date: Wed, 7 Dec 2022 12:14:05 -0800 Subject: 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. --- proxy_network.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'proxy_network.c') 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; } -- cgit v1.2.1