src/server/util/io.c

changeset 513
9a49c245a49c
parent 502
11ac3761c0e3
--- 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) {

mercurial