- Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
downloaded data in two buffers, just to be able to deal with a special HTTP pipelining case. That is now only activated for pipelined transfers. In Matt's case, it showed as a considerable performance difference,
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -6,6 +6,12 @@
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Daniel (3 January 2007)
|
||||||
|
- Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
|
||||||
|
downloaded data in two buffers, just to be able to deal with a special HTTP
|
||||||
|
pipelining case. That is now only activated for pipelined transfers. In
|
||||||
|
Matt's case, it showed as a considerable performance difference,
|
||||||
|
|
||||||
Daniel (2 January 2007)
|
Daniel (2 January 2007)
|
||||||
- Victor Snezhko helped us fix bug report #1603712
|
- Victor Snezhko helped us fix bug report #1603712
|
||||||
(http://curl.haxx.se/bug/view.cgi?id=1603712) (known bug #36) --limit-rate
|
(http://curl.haxx.se/bug/view.cgi?id=1603712) (known bug #36) --limit-rate
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ This release includes the following bugfixes:
|
|||||||
o libcurl.pc now uses Libs.private for "private" libs
|
o libcurl.pc now uses Libs.private for "private" libs
|
||||||
o --limit-rate (CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE)
|
o --limit-rate (CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE)
|
||||||
now work on windows again
|
now work on windows again
|
||||||
|
o improved download performance by avoiding the unconditional "double copying"
|
||||||
|
|
||||||
Other curl-related news:
|
Other curl-related news:
|
||||||
|
|
||||||
|
|||||||
35
lib/sendf.c
35
lib/sendf.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "connect.h" /* for the Curl_sockerrno() proto */
|
#include "connect.h" /* for the Curl_sockerrno() proto */
|
||||||
#include "sslgen.h"
|
#include "sslgen.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
|
#include "multiif.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -453,7 +454,7 @@ CURLcode Curl_client_write(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIN(a,b) (a < b ? a : b)
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal read-from-socket function. This is meant to deal with plain
|
* Internal read-from-socket function. This is meant to deal with plain
|
||||||
@@ -469,8 +470,10 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
ssize_t *n) /* amount bytes read */
|
ssize_t *n) /* amount bytes read */
|
||||||
{
|
{
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
size_t bytestocopy = MIN(conn->buf_len - conn->read_pos, sizerequested);
|
|
||||||
size_t bytesfromsocket = 0;
|
size_t bytesfromsocket = 0;
|
||||||
|
char *buffertofill = NULL;
|
||||||
|
bool pipelining = (conn->data->multi &&
|
||||||
|
Curl_multi_canPipeline(conn->data->multi));
|
||||||
|
|
||||||
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
||||||
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
||||||
@@ -479,6 +482,10 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
|
|
||||||
*n=0; /* reset amount to zero */
|
*n=0; /* reset amount to zero */
|
||||||
|
|
||||||
|
/* If session can pipeline, check connection buffer */
|
||||||
|
if(pipelining) {
|
||||||
|
size_t bytestocopy = MIN(conn->buf_len - conn->read_pos, sizerequested);
|
||||||
|
|
||||||
/* Copy from our master buffer first if we have some unread data there*/
|
/* Copy from our master buffer first if we have some unread data there*/
|
||||||
if (bytestocopy > 0) {
|
if (bytestocopy > 0) {
|
||||||
memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
|
memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
|
||||||
@@ -488,13 +495,19 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
*n = (ssize_t)bytestocopy;
|
*n = (ssize_t)bytestocopy;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we come here, it means that there is no data to read from the buffer,
|
/* If we come here, it means that there is no data to read from the buffer,
|
||||||
* so we read from the socket */
|
* so we read from the socket */
|
||||||
bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
|
bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
|
||||||
|
buffertofill = conn->master_buffer;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bytesfromsocket = MIN((long)sizerequested, conn->data->set.buffer_size ?
|
||||||
|
conn->data->set.buffer_size : BUFSIZE);
|
||||||
|
buffertofill = buf;
|
||||||
|
}
|
||||||
|
|
||||||
if(conn->ssl[num].use) {
|
if(conn->ssl[num].use) {
|
||||||
nread = Curl_ssl_recv(conn, num, conn->master_buffer, bytesfromsocket);
|
nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket);
|
||||||
|
|
||||||
if(nread == -1) {
|
if(nread == -1) {
|
||||||
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
|
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
|
||||||
@@ -502,20 +515,20 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
}
|
}
|
||||||
#ifdef USE_LIBSSH2
|
#ifdef USE_LIBSSH2
|
||||||
else if (conn->protocol & PROT_SCP) {
|
else if (conn->protocol & PROT_SCP) {
|
||||||
nread = Curl_scp_recv(conn, num, conn->master_buffer, bytesfromsocket);
|
nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
|
||||||
/* TODO: return CURLE_OK also for nread <= 0
|
/* TODO: return CURLE_OK also for nread <= 0
|
||||||
read failures and timeouts ? */
|
read failures and timeouts ? */
|
||||||
}
|
}
|
||||||
else if (conn->protocol & PROT_SFTP) {
|
else if (conn->protocol & PROT_SFTP) {
|
||||||
nread = Curl_sftp_recv(conn, num, conn->master_buffer, bytesfromsocket);
|
nread = Curl_sftp_recv(conn, num, buffertofill, bytesfromsocket);
|
||||||
}
|
}
|
||||||
#endif /* !USE_LIBSSH2 */
|
#endif /* !USE_LIBSSH2 */
|
||||||
else {
|
else {
|
||||||
if(conn->sec_complete)
|
if(conn->sec_complete)
|
||||||
nread = Curl_sec_read(conn, sockfd, conn->master_buffer,
|
nread = Curl_sec_read(conn, sockfd, buffertofill,
|
||||||
bytesfromsocket);
|
bytesfromsocket);
|
||||||
else
|
else
|
||||||
nread = sread(sockfd, conn->master_buffer, bytesfromsocket);
|
nread = sread(sockfd, buffertofill, bytesfromsocket);
|
||||||
|
|
||||||
if(-1 == nread) {
|
if(-1 == nread) {
|
||||||
int err = Curl_sockerrno();
|
int err = Curl_sockerrno();
|
||||||
@@ -529,10 +542,12 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nread >= 0) {
|
if (nread >= 0) {
|
||||||
|
if(pipelining) {
|
||||||
memcpy(buf, conn->master_buffer, nread);
|
memcpy(buf, conn->master_buffer, nread);
|
||||||
|
|
||||||
conn->buf_len = nread;
|
conn->buf_len = nread;
|
||||||
conn->read_pos = nread;
|
conn->read_pos = nread;
|
||||||
|
}
|
||||||
|
|
||||||
*n = nread;
|
*n = nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user