From 01b9bbb0f94e4ddd4b1e3ad678b220ca09bc0ad0 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Thu, 4 Jun 2020 14:11:07 -0700 Subject: Avoid a deadlock due to huge amounts of verbose messages. Allow the receiver to increase their iobuf.msg xbuf if it fills up. This ensures that the receiver will never block trying to output a message, and thus it will always drain the data from the sender and keep the whole thing from clogging up. --- io.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'io.c') diff --git a/io.c b/io.c index 999c34e5..ceff3784 100644 --- a/io.c +++ b/io.c @@ -954,8 +954,17 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert) } else #endif needed = len + 4 + 3; - if (iobuf.msg.len + needed > iobuf.msg.size) - perform_io(needed, PIO_NEED_MSGROOM); + if (iobuf.msg.len + needed > iobuf.msg.size) { + if (!am_receiver) + perform_io(needed, PIO_NEED_MSGROOM); + else { /* We allow the receiver to increase their iobuf.msg size to avoid a deadlock. */ + size_t old_size = iobuf.msg.size; + restore_iobuf_size(&iobuf.msg); + realloc_xbuf(&iobuf.msg, iobuf.msg.size * 2); + if (iobuf.msg.pos + iobuf.msg.len > old_size) + memcpy(iobuf.msg.buf + old_size, iobuf.msg.buf, iobuf.msg.pos + iobuf.msg.len - old_size); + } + } pos = iobuf.msg.pos + iobuf.msg.len; /* Must be set after any flushing. */ if (pos >= iobuf.msg.size) @@ -1176,7 +1185,7 @@ int read_line(int fd, char *buf, size_t bufsiz, int flags) #ifdef ICONV_OPTION if (flags & RL_CONVERT && iconv_buf.size < bufsiz) - realloc_xbuf(&iconv_buf, bufsiz + 1024); + realloc_xbuf(&iconv_buf, ROUND_UP_1024(bufsiz) + 1024); #endif start: -- cgit v1.2.1