]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
winsock: move SO_SNDBUF update into cf-socket
authorStefan Eissing <stefan@eissing.org>
Fri, 24 May 2024 08:09:32 +0000 (10:09 +0200)
committerJay Satiro <raysatiro@yahoo.com>
Wed, 29 May 2024 17:23:15 +0000 (13:23 -0400)
- Move the code that updates the SO_SNDBUF size for Windows to
  cf_socket_send.

Prior to this change the code was in readwrite_upload but the socket
filter is the more appropriate place because it applies to all sends.

Background:

For Windows users SO_SNDBUF (the total per-socket buffer size reserved
by Winsock for sends) is updated dynamically by libcurl during the
transfer. This is because Windows does not do it automatically for
non-blocking sockets and without it the performance of large transfers
may suffer.

Closes https://github.com/curl/curl/pull/13763

lib/cf-socket.c
lib/transfer.c
lib/urldata.h

index 3e87889f9c4f037c491c280cac34743ebc068b20..b5edaff71774ec6095c30adf854ed442ffeecd3f 100644 (file)
@@ -395,8 +395,26 @@ void Curl_sndbufset(curl_socket_t sockfd)
 
   setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
 }
+
+#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
+#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
 #endif
 
+static void win_update_buffer_size(curl_socket_t sockfd)
+{
+  int result;
+  ULONG ideal;
+  DWORD ideallen;
+  result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
+                    &ideal, sizeof(ideal), &ideallen, 0, 0);
+  if(result == 0) {
+    setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
+               (const char *)&ideal, sizeof(ideal));
+  }
+}
+
+#endif /* USE_WINSOCK */
+
 #ifndef CURL_DISABLE_BINDLOCAL
 static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
                           curl_socket_t sockfd, int af, unsigned int scope)
@@ -770,6 +788,9 @@ struct cf_socket_ctx {
   struct curltime started_at;        /* when socket was created */
   struct curltime connected_at;      /* when socket connected/got first byte */
   struct curltime first_byte_at;     /* when first byte was recvd */
+#ifdef USE_WINSOCK
+  struct curltime last_sndbuf_update; /* last update of sendbuf */
+#endif
   int error;                         /* errno of last failure or 0 */
 #ifdef DEBUGBUILD
   int wblock_percent;                /* percent of writes doing EAGAIN */
@@ -1336,6 +1357,16 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
   }
 
+#if defined(USE_WINSOCK)
+  if(!*err) {
+    struct curltime n = Curl_now();
+    if(Curl_timediff(n, ctx->last_sndbuf_update) > 1000) {
+      win_update_buffer_size(ctx->sock);
+      ctx->last_sndbuf_update = n;
+    }
+  }
+#endif
+
   CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, err=%d",
               orig_len, (int)nwritten, *err);
   cf->conn->sock[cf->sockindex] = fdsave;
index b0783581cc7992a78da5014a03a560ace693cd10..cbd91d0e27a849577e7fd43cba7f29e86d77afa4 100644 (file)
@@ -320,34 +320,11 @@ out:
   return result;
 }
 
-#if defined(_WIN32) && defined(USE_WINSOCK)
-#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
-#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
-#endif
-
-static void win_update_buffer_size(curl_socket_t sockfd)
-{
-  int result;
-  ULONG ideal;
-  DWORD ideallen;
-  result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
-                    &ideal, sizeof(ideal), &ideallen, 0, 0);
-  if(result == 0) {
-    setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
-               (const char *)&ideal, sizeof(ideal));
-  }
-}
-#else
-#define win_update_buffer_size(x)
-#endif
-
 /*
  * Send data to upload to the server, when the socket is writable.
  */
 static CURLcode readwrite_upload(struct Curl_easy *data, int *didwhat)
 {
-  CURLcode result = CURLE_OK;
-
   if((data->req.keepon & KEEP_SEND_PAUSE))
     return CURLE_OK;
 
@@ -358,23 +335,9 @@ static CURLcode readwrite_upload(struct Curl_easy *data, int *didwhat)
 
   if(!Curl_req_done_sending(data)) {
     *didwhat |= KEEP_SEND;
-    result = Curl_req_send_more(data);
-    if(result)
-      return result;
-
-#if defined(_WIN32) && defined(USE_WINSOCK)
-    /* FIXME: this looks like it would fit better into cf-socket.c
-     * but then I do not know enough Windows to say... */
-    {
-      struct curltime n = Curl_now();
-      if(Curl_timediff(n, data->conn->last_sndbuf_update) > 1000) {
-        win_update_buffer_size(data->conn->writesockfd);
-        data->conn->last_sndbuf_update = n;
-      }
-    }
-#endif
+    return Curl_req_send_more(data);
   }
-  return result;
+  return CURLE_OK;
 }
 
 static int select_bits_paused(struct Curl_easy *data, int select_bits)
index 48844d2707ed0a71aa46cc4dd26958cb30307fac..f55ba5027d673faf18729b6a61ff171048fc8934 100644 (file)
@@ -908,11 +908,6 @@ struct connectdata {
   CtxtHandle *sslContext;
 #endif
 
-#if defined(_WIN32) && defined(USE_WINSOCK)
-  struct curltime last_sndbuf_update;  /* last time readwrite_upload called
-                                          win_update_buffer_size */
-#endif
-
 #ifdef USE_GSASL
   struct gsasldata gsasl;
 #endif