Index: docs/libcurl/curl_multi_perform.3
===================================================================
RCS file: /cvsroot/curl/curl/docs/libcurl/curl_multi_perform.3,v
retrieving revision 1.10
diff -u -p -r1.10 curl_multi_perform.3
--- docs/libcurl/curl_multi_perform.3	2 Sep 2009 14:57:05 -0000	1.10
+++ docs/libcurl/curl_multi_perform.3	31 Jan 2010 14:23:17 -0000
@@ -22,7 +22,8 @@ changed from the previous call (or is le
 you've added to the multi handle), you know that there is one or more
 transfers less "running". You can then call \fIcurl_multi_info_read(3)\fP to
 get information about each individual completed transfer, and that returned
-info includes CURLcode and more.
+info includes CURLcode and more. If an added handle fails very quickly, it may
+never be counted as a running_handle.
 
 When \fIrunning_handles\fP is set to zero (0) on the return of this function,
 there is no longer any transfers in progress.
Index: lib/multi.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/multi.c,v
retrieving revision 1.210
diff -u -p -r1.210 multi.c
--- lib/multi.c	28 Jan 2010 15:34:18 -0000	1.210
+++ lib/multi.c	31 Jan 2010 14:23:17 -0000
@@ -1568,17 +1568,6 @@ static CURLMcode multi_runsingle(struct 
     multi->num_msgs++; /* increase message counter */
   }
 
-  if(CURLM_CALL_MULTI_PERFORM == result)
-    /* Set the timeout for this handle to expire really soon so that it will
-       be taken care of even when this handle is added in the midst of
-       operation when only the curl_multi_socket() API is used. During that
-       flow, only sockets that time-out or have actions will be dealt
-       with. Since this handle has no action yet, we make sure it times out to
-       get things to happen. Also, this makes it less important for callers of
-       the curl_multi_* functions to bother about the CURLM_CALL_MULTI_PERFORM
-       return code, as long as they deal with the timeouts properly. */
-    Curl_expire(easy->easy_handle, 1);
-
   return result;
 }
 
@@ -1597,7 +1586,10 @@ CURLMcode curl_multi_perform(CURLM *mult
   while(easy != &multi->easy) {
     CURLMcode result;
 
-    result = multi_runsingle(multi, easy);
+    do
+      result = multi_runsingle(multi, easy);
+    while (CURLM_CALL_MULTI_PERFORM == result);
+
     if(result)
       returncode = result;
 
@@ -1956,7 +1948,9 @@ static CURLMcode multi_socket(struct Cur
       if(data->set.one_easy->easy_conn)  /* set socket event bitmask */
         data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
 
-      result = multi_runsingle(multi, data->set.one_easy);
+      do
+        result = multi_runsingle(multi, data->set.one_easy);
+      while (CURLM_CALL_MULTI_PERFORM == result);
 
       if(data->set.one_easy->easy_conn)
         data->set.one_easy->easy_conn->cselect_bits = 0;
@@ -1985,7 +1979,9 @@ static CURLMcode multi_socket(struct Cur
 
     /* the first loop lap 'data' can be NULL */
     if(data) {
-      result = multi_runsingle(multi, data->set.one_easy);
+      do
+        result = multi_runsingle(multi, data->set.one_easy);
+      while (CURLM_CALL_MULTI_PERFORM == result);
 
       if(CURLM_OK >= result)
         /* get the socket(s) and check if the state has been changed since
