mirror of
https://github.com/curl/curl.git
synced 2024-12-27 06:59:43 +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));
|
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
|
#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
|
#ifndef CURL_DISABLE_BINDLOCAL
|
||||||
static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||||
curl_socket_t sockfd, int af, unsigned int scope)
|
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 started_at; /* when socket was created */
|
||||||
struct curltime connected_at; /* when socket connected/got first byte */
|
struct curltime connected_at; /* when socket connected/got first byte */
|
||||||
struct curltime first_byte_at; /* when first byte was recvd */
|
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 */
|
int error; /* errno of last failure or 0 */
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
int wblock_percent; /* percent of writes doing EAGAIN */
|
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",
|
CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, err=%d",
|
||||||
orig_len, (int)nwritten, *err);
|
orig_len, (int)nwritten, *err);
|
||||||
cf->conn->sock[cf->sockindex] = fdsave;
|
cf->conn->sock[cf->sockindex] = fdsave;
|
||||||
|
@ -320,34 +320,11 @@ out:
|
|||||||
return result;
|
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.
|
* Send data to upload to the server, when the socket is writable.
|
||||||
*/
|
*/
|
||||||
static CURLcode readwrite_upload(struct Curl_easy *data, int *didwhat)
|
static CURLcode readwrite_upload(struct Curl_easy *data, int *didwhat)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
if((data->req.keepon & KEEP_SEND_PAUSE))
|
if((data->req.keepon & KEEP_SEND_PAUSE))
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
@ -358,23 +335,9 @@ static CURLcode readwrite_upload(struct Curl_easy *data, int *didwhat)
|
|||||||
|
|
||||||
if(!Curl_req_done_sending(data)) {
|
if(!Curl_req_done_sending(data)) {
|
||||||
*didwhat |= KEEP_SEND;
|
*didwhat |= KEEP_SEND;
|
||||||
result = Curl_req_send_more(data);
|
return 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 CURLE_OK;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int select_bits_paused(struct Curl_easy *data, int select_bits)
|
static int select_bits_paused(struct Curl_easy *data, int select_bits)
|
||||||
|
@ -908,11 +908,6 @@ struct connectdata {
|
|||||||
CtxtHandle *sslContext;
|
CtxtHandle *sslContext;
|
||||||
#endif
|
#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
|
#ifdef USE_GSASL
|
||||||
struct gsasldata gsasl;
|
struct gsasldata gsasl;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user