mirror of
https://github.com/curl/curl.git
synced 2024-12-21 06:50:10 +08:00
winsock: move SO_SNDBUF update into cf-socket
- 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
This commit is contained in:
parent
2b52fe4115
commit
0b520e1250
@ -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;
|
||||
|
@ -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;
|
||||
return Curl_req_send_more(data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int select_bits_paused(struct Curl_easy *data, int select_bits)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user