[117022] trunk/base/src/pextlib1.0/curl.c
cal at macports.org
cal at macports.org
Wed Feb 12 15:55:31 PST 2014
Revision: 117022
https://trac.macports.org/changeset/117022
Author: cal at macports.org
Date: 2014-02-12 15:55:31 -0800 (Wed, 12 Feb 2014)
Log Message:
-----------
pextlib1.0/curl.c: Use only a single cURL handle
- This change makes this code no longer thread safe, which is not a problem
because we're not using it from different threads anyway.
- The change also makes cURL re-use connections with HTTP Keep-Alive, speeding
up downloading binary packages and their checksum. For binary-only
installations of small packages the installation is often fast enough to
re-use the same connection for the next port, too.
- This creates a (delibarate) memory leak, since the curl handle is never
cleaned up.
Modified Paths:
--------------
trunk/base/src/pextlib1.0/curl.c
Modified: trunk/base/src/pextlib1.0/curl.c
===================================================================
--- trunk/base/src/pextlib1.0/curl.c 2014-02-12 23:36:40 UTC (rev 117021)
+++ trunk/base/src/pextlib1.0/curl.c 2014-02-12 23:55:31 UTC (rev 117022)
@@ -63,6 +63,13 @@
#pragma mark Definitions
/* ------------------------------------------------------------------------- **
+ * Global cURL handle
+ * ------------------------------------------------------------------------- */
+/* we use a single global handle rather than creating and destroying handles to
+ * take advantage of HTTP pipelining, especially to the packages servers. */
+static CURL* theHandle = NULL;
+
+/* ------------------------------------------------------------------------- **
* Prototypes
* ------------------------------------------------------------------------- */
int SetResultFromCurlErrorCode(Tcl_Interp* interp, CURLcode inErrorCode);
@@ -115,7 +122,6 @@
CurlFetchCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
{
int theResult = TCL_OK;
- CURL* theHandle = NULL;
FILE* theFile = NULL;
bool performFailed = false;
char theErrorString[CURL_ERROR_SIZE];
@@ -221,7 +227,7 @@
}
/* Open the file */
- theFile = fopen( theFilePath, "w" );
+ theFile = fopen(theFilePath, "w");
if (theFile == NULL) {
Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
theResult = TCL_ERROR;
@@ -229,7 +235,12 @@
}
/* Create the CURL handle */
- theHandle = curl_easy_init();
+ if (theHandle == NULL) {
+ /* Re-use existing handle if theHandle isn't NULL */
+ theHandle = curl_easy_init();
+ }
+ /* If we're re-using a handle, the previous call did ensure to reset it
+ * to the default state using curl_easy_reset(3) */
/* Setup the handle */
theCurlCode = curl_easy_setopt(theHandle, CURLOPT_URL, theURL);
@@ -388,7 +399,7 @@
}
/* close the file */
- (void) fclose( theFile );
+ (void) fclose(theFile);
theFile = NULL;
#if LIBCURL_VERSION_NUM == 0x070d01 /* work around broken Tiger version of cURL */
@@ -405,21 +416,21 @@
theResult = TCL_ERROR;
break;
}
- theFile = fopen( theFilePath, "r");
+ theFile = fopen(theFilePath, "r");
if (theFile == NULL) {
Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
theResult = TCL_ERROR;
break;
}
- if ( (p = fgets(buf, BUFSIZ, theFile)) != NULL) {
+ if ((p = fgets(buf, BUFSIZ, theFile)) != NULL) {
/* skip stray header escaping into output */
if (strncmp(p, "Last-Modified:", 14) != 0)
rewind(theFile);
}
- while ( (size = fread(buf, 1, BUFSIZ, theFile)) > 0) {
+ while ((size = fread(buf, 1, BUFSIZ, theFile)) > 0) {
fwrite(buf, 1, size, fp);
}
- (void) fclose( theFile );
+ (void) fclose(theFile);
theFile = NULL;
fclose(fp);
if (rename(tmp, theFilePath) != 0) {
@@ -450,10 +461,6 @@
(effectiveURL == NULL || theCurlCode != CURLE_OK) ? "" : effectiveURL,
0);
}
-
- /* clean up */
- curl_easy_cleanup( theHandle );
- theHandle = NULL;
} while (0);
if (performFailed) {
@@ -461,11 +468,12 @@
theResult = TCL_ERROR;
}
+ /* reset the connection */
if (theHandle != NULL) {
- curl_easy_cleanup( theHandle );
+ curl_easy_reset(theHandle);
}
if (theFile != NULL) {
- fclose( theFile );
+ fclose(theFile);
}
return theResult;
@@ -511,7 +519,7 @@
}
optioncrsr++;
- }
+ }
if (optioncrsr <= lastoption) {
/* something went wrong */
@@ -535,7 +543,7 @@
}
/* Open the file (dev/null) */
- theFile = fopen( "/dev/null", "a" );
+ theFile = fopen("/dev/null", "a");
if (theFile == NULL) {
Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
theResult = TCL_ERROR;
@@ -543,7 +551,12 @@
}
/* Create the CURL handle */
- theHandle = curl_easy_init();
+ if (theHandle == NULL) {
+ /* Re-use existing handle if theHandle isn't NULL */
+ theHandle = curl_easy_init();
+ }
+ /* If we're re-using a handle, the previous call did ensure to reset it
+ * to the default state using curl_easy_reset(3) */
/* Setup the handle */
theCurlCode = curl_easy_setopt(theHandle, CURLOPT_URL, theURL);
@@ -656,7 +669,7 @@
}
/* close the file */
- (void) fclose( theFile );
+ (void) fclose(theFile);
theFile = NULL;
/* check everything went fine */
@@ -676,10 +689,6 @@
break;
}
- /* clean up */
- curl_easy_cleanup( theHandle );
- theHandle = NULL;
-
/* compare this with the date provided by user */
if (theModDate < -1) {
Tcl_SetResult(interp, "Couldn't get resource modification date", TCL_STATIC);
@@ -695,8 +704,9 @@
}
} while (0);
+ /* reset the connection */
if (theHandle != NULL) {
- curl_easy_cleanup(theHandle);
+ curl_easy_reset(theHandle);
}
if (theFile != NULL) {
@@ -763,7 +773,7 @@
theURL = Tcl_GetString(objv[objc - 1]);
/* Open the file (dev/null) */
- theFile = fopen( "/dev/null", "a" );
+ theFile = fopen("/dev/null", "a");
if (theFile == NULL) {
Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
theResult = TCL_ERROR;
@@ -771,7 +781,12 @@
}
/* Create the CURL handle */
- theHandle = curl_easy_init();
+ if (theHandle == NULL) {
+ /* Re-use existing handle if theHandle isn't NULL */
+ theHandle = curl_easy_init();
+ }
+ /* If we're re-using a handle, the previous call did ensure to reset it
+ * to the default state using curl_easy_reset(3) */
/* Setup the handle */
theCurlCode = curl_easy_setopt(theHandle, CURLOPT_URL, theURL);
@@ -879,7 +894,7 @@
}
/* close the file */
- (void) fclose( theFile );
+ (void) fclose(theFile);
theFile = NULL;
theFileSize = 0.0;
@@ -891,17 +906,14 @@
break;
}
- /* clean up */
- curl_easy_cleanup( theHandle );
- theHandle = NULL;
-
(void) snprintf(theSizeString, sizeof(theSizeString),
"%.0f", theFileSize);
Tcl_SetResult(interp, theSizeString, TCL_VOLATILE);
} while (0);
+ /* reset the connection */
if (theHandle != NULL) {
- curl_easy_cleanup(theHandle);
+ curl_easy_reset(theHandle);
}
if (theFile != NULL) {
@@ -943,7 +955,7 @@
/* Retrieve the post data - it's before the url */
thePostData = Tcl_GetString(objv[objc - 2]);
/* Open the file (dev/null) */
- theFile = fopen( "/dev/null", "a" );
+ theFile = fopen("/dev/null", "a");
if (theFile == NULL) {
Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
theResult = TCL_ERROR;
@@ -951,7 +963,12 @@
}
/* Create the CURL handle */
- theHandle = curl_easy_init();
+ if (theHandle == NULL) {
+ /* Re-use existing handle if theHandle isn't NULL */
+ theHandle = curl_easy_init();
+ }
+ /* If we're re-using a handle, the previous call did ensure to reset it
+ * to the default state using curl_easy_reset(3) */
/* Setup the handle */
theCurlCode = curl_easy_setopt(theHandle, CURLOPT_URL, theURL);
@@ -1045,16 +1062,13 @@
}
/* close the file */
- (void) fclose( theFile );
+ (void) fclose(theFile);
theFile = NULL;
-
- /* clean up */
- curl_easy_cleanup( theHandle );
- theHandle = NULL;
} while (0);
+ /* reset the connection */
if (theHandle != NULL) {
- curl_easy_cleanup(theHandle);
+ curl_easy_reset(theHandle);
}
if (theFile != NULL) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20140212/8bb96ab6/attachment-0001.html>
More information about the macports-changes
mailing list