]> granicus.if.org Git - curl/commitdiff
conncache: use conn->data to know if a transfer owns it
authorDaniel Stenberg <daniel@haxx.se>
Sat, 16 Mar 2019 23:49:21 +0000 (00:49 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 17 Mar 2019 17:07:20 +0000 (18:07 +0100)
- make sure an already "owned" connection isn't returned unless
  multiplexed.

- clear ->data when returning the connection to the cache again

Regression since 7.62.0 (probably in commit 1b76c38904f0)

Bug: https://curl.haxx.se/mail/lib-2019-03/0064.html

Closes #3686

lib/conncache.c
lib/url.c

index c975c456ebc125e9ebd7bf436ea2efe9a37166db..39302ba7bafb9b5704aaf9051ec688fe71e8eb91 100644 (file)
@@ -433,6 +433,7 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
     data->multi->maxconnects;
   struct connectdata *conn_candidate = NULL;
 
+  conn->data = NULL; /* no owner anymore */
   if(maxconnects > 0 &&
      Curl_conncache_size(data) > maxconnects) {
     infof(data, "Connection cache is full, closing the oldest one.\n");
@@ -476,7 +477,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
   while(curr) {
     conn = curr->ptr;
 
-    if(!CONN_INUSE(conn)) {
+    if(!CONN_INUSE(conn) && !conn->data) {
       /* Set higher score for the age passed since the connection was used */
       score = Curl_timediff(now, conn->now);
 
@@ -534,7 +535,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
     while(curr) {
       conn = curr->ptr;
 
-      if(!CONN_INUSE(conn)) {
+      if(!CONN_INUSE(conn) && !conn->data) {
         /* Set higher score for the age passed since the connection was used */
         score = Curl_timediff(now, conn->now);
 
index e67def5fc581d963d37d5ea40fa7ce2f7df71ad9..eb09a24be29d23f9bc294f52158910609bafa5a4 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -975,7 +975,7 @@ static bool extract_if_dead(struct connectdata *conn,
                             struct Curl_easy *data)
 {
   size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
-  if(!pipeLen && !CONN_INUSE(conn)) {
+  if(!pipeLen && !CONN_INUSE(conn) && !conn->data) {
     /* The check for a dead socket makes sense only if there are no
        handles in pipeline and the connection isn't already marked in
        use */
@@ -1287,14 +1287,15 @@ ConnectionExists(struct Curl_easy *data,
         }
       }
 
-      if(!canpipe && CONN_INUSE(check))
+      if(!canpipe && check->data)
         /* this request can't be pipelined but the checked connection is
            already in use so we skip it */
         continue;
 
-      if(CONN_INUSE(check) && (check->data->multi != needle->data->multi))
-        /* this could be subject for pipeline/multiplex use, but only
-           if they belong to the same multi handle */
+      if(CONN_INUSE(check) && check->data &&
+         (check->data->multi != needle->data->multi))
+        /* this could be subject for pipeline/multiplex use, but only if they
+           belong to the same multi handle */
         continue;
 
       if(needle->localdev || needle->localport) {
@@ -3420,6 +3421,8 @@ static CURLcode resolve_server(struct Curl_easy *data,
   CURLcode result = CURLE_OK;
   timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
+  DEBUGASSERT(conn);
+  DEBUGASSERT(data);
   /*************************************************************
    * Resolve the name of the server or proxy
    *************************************************************/