Index: lib/multi.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/multi.c,v
retrieving revision 1.105
diff -u -r1.105 multi.c
--- lib/multi.c	16 Sep 2006 21:50:29 -0000	1.105
+++ lib/multi.c	18 Sep 2006 21:43:18 -0000
@@ -207,9 +207,9 @@
     index = easy->easy_conn->connectindex;
 
   infof(easy->easy_handle,
-        "STATE: %s => %s handle %p; (connection #%ld) \n",
+        "STATE: %s => %s handle %p; easy %p (connection #%ld) \n",
         statename[oldstate], statename[easy->state],
-        (char *)easy, index);
+        (char *)easy, easy->easy_handle, index);
 #endif
   if(state == CURLM_STATE_COMPLETED)
     /* changing to COMPLETED means there's one less easy handle 'alive' */
@@ -424,12 +424,10 @@
   /* increase the node-counter */
   multi->num_easy++;
 
-  if((multi->num_easy+5) > multi->connc->num) {
-    /* we want the connection cache to have room for all easy transfers, and
-       some more so we have a margin of 5 for now, but we add the new amount
-       plus 10 to not have to do it for every new handle added */
+  if((multi->num_easy * 15) > multi->connc->num) {
+    /* we want the connection cache to have plenty room for easy transfers */
     CURLcode res = Curl_ch_connc(easy_handle, multi->connc,
-                                 multi->num_easy + 10);
+                                 multi->connc->num*15);
     if(res)
       /* TODO: we need to do some cleaning up here! */
       return res;
@@ -1179,6 +1177,18 @@
 
       /* This node should be delinked from the list now and we should post
          an information message that we are complete. */
+
+#if 0
+      /* Remove ourselves from the receive pipeline, which already SHOULD
+         have happened but we make an extra caution here since we seem to
+         somehow end up here still in the pipe... */
+      fprintf(stderr, "COMPLETE: easy %p conn %p\n",
+              easy->easy_handle,
+              easy->easy_conn);
+      if(easy->easy_conn)
+        Curl_removeHandleFromPipeline(easy->easy_handle,
+                                      easy->easy_conn->recv_pipe);
+#endif
       break;
 
     case CURLM_STATE_CANCELLED:
Index: lib/url.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/url.c,v
retrieving revision 1.535
diff -u -r1.535 url.c
--- lib/url.c	16 Sep 2006 21:50:29 -0000	1.535
+++ lib/url.c	18 Sep 2006 21:43:19 -0000
@@ -216,6 +216,44 @@
 {
   struct Curl_multi *m = data->multi;
 
+#if 1 /* only for debugging, scan through all connections and see if there's
+         a pipe reference still identifying this handle */
+  if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) {
+    struct conncache *c = data->state.connc;
+    int i;
+    struct curl_llist *pipe;
+    struct curl_llist_element *curr;
+    struct connectdata *connptr;
+
+    for(i=0; i< c->num; i++) {
+      connptr = c->connects[i];
+      if(!connptr)
+        continue;
+
+      pipe = connptr->send_pipe;
+      if(pipe) {
+        for (curr = pipe->head; curr; curr=curr->next) {
+          if(data == (struct SessionHandle *) curr->ptr) {
+            fprintf(stderr,
+                    "MAJOR problem we %p are still in send pipe for %p\n",
+                    data, connptr);
+          }
+        }
+      }
+      pipe = connptr->recv_pipe;
+      if(pipe) {
+        for (curr = pipe->head; curr; curr=curr->next) {
+          if(data == (struct SessionHandle *) curr->ptr) {
+            fprintf(stderr,
+                    "MAJOR problem we %p are still in recv pipe for %p\n",
+                    data, connptr);
+          }
+        }
+      }
+    }
+  }
+#endif
+
   if(m)
     /* This handle is still part of a multi handle, take care of this first
        and detach this handle from there. */
@@ -1707,6 +1745,11 @@
     return CURLE_OK; /* this is closed and fine already */
   data = conn->data;
 
+  if(!data) {
+    fprintf(stderr, "DISCONNECT without easy handle, ignoring\n");
+    return CURLE_OK;
+  }
+
 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
   /* scan for DNS cache entries still marked as in use */
   Curl_hash_apply(data->hostcache,
@@ -1864,7 +1907,14 @@
     struct curl_llist_element *next = curr->next;
     struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
 
-    data->state.pipe_broke = TRUE;
+#if 1 /* debug-only code */
+    if(data->magic != CURLEASY_MAGIC_NUMBER) {
+      /* MAJOR BADNESS */
+      fprintf(stderr, "signalPipeClose() found BAAD easy handle\n");
+    }
+    else
+#endif
+      data->state.pipe_broke = TRUE;
 
     Curl_llist_remove(pipe, curr, NULL);
     curr = next;
@@ -2062,7 +2112,7 @@
 
   if (conn->send_pipe == 0 &&
       conn->recv_pipe == 0)
-      conn->is_in_pipeline = FALSE;
+    conn->is_in_pipeline = FALSE;
 }
 
 /*
@@ -2086,7 +2136,8 @@
     /* there was no room available, kill one */
     i = ConnectionKillOne(data);
     if(-1 != i)
-      infof(data, "Connection (#%d) was killed to make room\n", i);
+      infof(data, "Connection (#%d) was killed to make room (holds %d)\n",
+            i, data->state.connc->num);
     else
       infof(data, "This connection did not fit in the connection cache\n");
   }
@@ -4438,6 +4489,8 @@
      cancelled before we proceed */
   ares_cancel(data->state.areschannel);
 
+  ConnectionDone(conn); /* the connection is no longer in use */
+
   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
      forced us to close this no matter what we think.
 
@@ -4463,8 +4516,6 @@
     infof(data, "Connection #%ld to host %s left intact\n",
           conn->connectindex,
           conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
-
-    ConnectionDone(conn); /* the connection is no longer in use */
   }
 
   return result;

