diff -r a5a142fea2ae -r 9a49c245a49c src/server/util/io.c --- a/src/server/util/io.c Tue Sep 12 18:08:11 2023 +0200 +++ b/src/server/util/io.c Sat Mar 30 12:35:09 2024 +0100 @@ -78,6 +78,7 @@ NULL, (io_setmode_f)net_sys_setmode, (io_poll_f)net_sys_poll, + 0, 0 }; @@ -90,7 +91,8 @@ (io_finish_f)net_http_finish, (io_setmode_f)net_http_setmode, (io_poll_f)net_http_poll, - 0 + 0, + IO_STREAM_TYPE_HTTP }; IOStream ssl_io_funcs = { @@ -102,9 +104,15 @@ (io_finish_f)net_ssl_finish, (io_setmode_f)net_ssl_setmode, (io_poll_f)net_ssl_poll, - 0 + 0, + IO_STREAM_TYPE_SSL }; +static int net_write_max_attempts = 16384; + +void io_set_max_writes(int n) { + net_write_max_attempts = 1; +} /* * Sysstream implementation @@ -300,7 +308,7 @@ } int httpstream_enable_chunked_write(IOStream *st) { - if(st->write != (io_write_f)net_http_write) { + if(st->type != IO_STREAM_TYPE_HTTP) { log_ereport(LOG_FAILURE, "%s", "httpstream_enable_chunked_write: IOStream is not an HttpStream"); return 1; } @@ -467,7 +475,7 @@ st->written += ret_w; if(ret_w == 0) { st->st.io_errno = EWOULDBLOCK; // not sure if this is really correct - ret_w = -1; + //ret_w = -1; } return ret_w; } @@ -876,11 +884,25 @@ } ssize_t net_write(SYS_NETFD fd, const void *buf, size_t nbytes) { - ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); - if(r < 0) { + size_t w = 0; + size_t remaining = nbytes; + const char *cbuf = buf; + ssize_t r = 0; + int attempts = 0; + while(w < nbytes && attempts < net_write_max_attempts) { + r = ((IOStream*)fd)->write(fd, cbuf, remaining); + if(r <= 0) { + break; + } + w += r; + cbuf += r; + remaining -= r; + attempts++; + } + if(r < 0 && w == 0) { return IO_ERROR; } - return r; + return w; } ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) {