On 19/06/14 17:20, Daniel Stenberg wrote:
Yes, that's an unfortunate side-effect of the modified connection cache in 7.30.0 I believe. It has been discussed before but nobody has stepped up to do the necessary work.

I devised a patch that would reintroduce the cleanup before other connections are established. But if you are wary about the performance this should perhaps be configurable by a easy_setopt() directive. What do you think?

cheers, Frank


diff --git a/lib/url.c b/lib/url.c
index 770b0cc..8e85d68 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2910,6 +2910,65 @@ find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
 }
 
 /*
+ * This function checks if given connection is dead and removes it from the
+ * connection cache if this is the case.
+ *
+ * Returns TRUE if the connection was dead and removed
+ */
+static bool RemoveConnectionIfDead(struct connectdata *check,
+    struct SessionHandle *data) {
+
+  size_t pipeLen = check->send_pipe->size + check->recv_pipe->size;
+  if (!pipeLen && !check->inuse) {
+    /* 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 */
+    bool dead;
+    if (check->handler->protocol & CURLPROTO_RTSP)
+      /* RTSP is a special case due to RTP interleaving */
+      dead = Curl_rtsp_connisdead(check);
+    else
+      dead = SocketIsDead(check->sock[FIRSTSOCKET]);
+
+    if (dead) {
+      check->data = data;
+      infof(data, "Connection %ld seems to be dead!\n", check->connection_id);
+
+      /* disconnect resources */
+      Curl_disconnect(check, /* dead_connection */TRUE);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+/*
+ * Wrapper to use RemoveConnectionIfDead() function in Curl_conncache_foreach()
+ *
+ * Returns always 0.
+ */
+static int RemoveConnectionIfDeadWrapper(struct connectdata *check,
+    void *param) {
+
+  struct SessionHandle* data = (struct SessionHandle*)param;
+
+  RemoveConnectionIfDead(check, data);
+
+  return 0; /* continue iteration */
+}
+
+
+/*
+ * This function scans the connection cache for half-open/dead connections,
+ * closes and removes them.
+ */
+static void CleanupDeadConnections(struct SessionHandle *data) {
+
+  Curl_conncache_foreach(data->state.conn_cache, data, RemoveConnectionIfDeadWrapper);
+}
+
+/*
  * Given one filled in connection struct (named needle), this function should
  * detect if there already is one that has all the significant details
  * exactly the same and thus should be used instead.
@@ -2973,29 +3032,10 @@ ConnectionExists(struct SessionHandle *data,
       check = curr->ptr;
       curr = curr->next;
 
-      pipeLen = check->send_pipe->size + check->recv_pipe->size;
-
-      if(!pipeLen && !check->inuse) {
-        /* 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 */
-        bool dead;
-        if(check->handler->protocol & CURLPROTO_RTSP)
-          /* RTSP is a special case due to RTP interleaving */
-          dead = Curl_rtsp_connisdead(check);
-        else
-          dead = SocketIsDead(check->sock[FIRSTSOCKET]);
-
-        if(dead) {
-          check->data = data;
-          infof(data, "Connection %ld seems to be dead!\n",
-                check->connection_id);
+      if (RemoveConnectionIfDead(check, data))
+        continue;
 
-          /* disconnect resources */
-          Curl_disconnect(check, /* dead_connection */ TRUE);
-          continue;
-        }
-      }
+      pipeLen = check->send_pipe->size + check->recv_pipe->size;
 
       if(canPipeline) {
         /* Make sure the pipe has only GET requests */
@@ -5456,6 +5496,10 @@ static CURLcode create_conn(struct SessionHandle *data,
     goto out;
   }
 
+
+  CleanupDeadConnections(data);
+
+
   /*************************************************************
    * Check the current list of connections to see if we can
    * re-use an already existing one or if we have to create a
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to