diff -u curl/include/curl/multi.h curl.jkp/include/curl/multi.h
--- curl/include/curl/multi.h	2006-09-07 20:26:25.000000000 -0500
+++ curl.jkp/include/curl/multi.h	2006-10-09 14:05:35.000000000 -0500
@@ -231,6 +231,20 @@
                                                         pointer */
                                     void *socketp);  /* private socket
                                                         pointer */
+/*
+ * Name:    curl_multi_timer_callback
+ *
+ * Desc:    Called by libcurl whenever the library detects a change in the 
+ *          maximum number of milliseconds the app is allowed to wait before
+ *          curl_multi_socket() or curl_multi_perform() must be called 
+ *          (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi,  /* multi handle */
+                                    long timeout_ms,    /* see above */
+                                    void *userp);       /* private callback
+                                                           pointer */
 
 CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
                                         int *running_handles);
@@ -272,6 +286,12 @@
 
     /* set to 1 to enable pipelining for this multi handle */
   CINIT(PIPELINING, LONG, 3),
+  
+   /* This is the timer callback function pointer */
+  CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+  /* This is the argument passed to the timer callback */
+  CINIT(TIMERDATA, OBJECTPOINT, 5),
 
   CURLMOPT_LASTENTRY /* the last unused */
 } CURLMoption;
diff -u curl/lib/multi.c curl.jkp/lib/multi.c
--- curl/lib/multi.c	2006-10-09 16:51:07.000000000 -0500
+++ curl.jkp/lib/multi.c	2006-10-10 03:47:20.000000000 -0500
@@ -18,7 +18,7 @@
  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  * KIND, either express or implied.
  *
- * $Id: multi.c,v 1.115 2006-10-09 21:24:34 bagder Exp $
+ * $Id: multi.c,v 1.114 2006-10-09 11:21:40 yangtse Exp $
  ***************************************************************************/
 
 #include "setup.h"
@@ -166,6 +166,12 @@
 
   /* list of easy handles kept around for doing nice connection closures */
   struct closure *closure;
+
+  /* timer callback and user data pointer for the *socket() API */
+  curl_multi_timer_callback timer_cb;
+  void *timer_userp;
+
+
 };
 
 static bool multi_conn_using(struct Curl_multi *multi,
@@ -174,6 +180,7 @@
                          struct Curl_one_easy *easy);
 static void add_closure(struct Curl_multi *multi,
                         struct SessionHandle *data);
+static int update_timer(struct Curl_multi *multi);
 
 /* always use this function to change state, to make debugging easier */
 static void multistate(struct Curl_one_easy *easy, CURLMstate state)
@@ -460,6 +467,7 @@
   /* increase the alive-counter */
   multi->num_alive++;
 
+  update_timer(multi);
   return CURLM_OK;
 }
 
@@ -610,6 +618,7 @@
 
     multi->num_easy--; /* one less to care about now */
 
+    update_timer(multi);
     return CURLM_OK;
   }
   else
@@ -1340,6 +1349,8 @@
 
   *running_handles = multi->num_alive;
 
+  if ( CURLM_OK == returncode )
+    update_timer(multi);
   return returncode;
 }
 
@@ -1671,6 +1682,12 @@
   case CURLMOPT_PIPELINING:
     multi->pipelining_enabled = (bool)(0 != va_arg(param, long));
     break;
+  case CURLMOPT_TIMERFUNCTION:
+    multi->timer_cb = va_arg(param, curl_multi_timer_callback);
+    break;
+  case CURLMOPT_TIMERDATA:
+    multi->timer_userp = va_arg(param, void *);
+    break;
   default:
     res = CURLM_UNKNOWN_OPTION;
   }
@@ -1682,15 +1699,23 @@
 CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
                             int *running_handles)
 {
-  return multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
+  CURLMcode result;
+  result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
                       running_handles);
+  if (CURLM_OK == result)
+    update_timer((struct Curl_multi *)multi_handle);
+  return result;
 }
 
 CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
 
 {
-  return multi_socket((struct Curl_multi *)multi_handle,
+  CURLMcode result;
+  result = multi_socket((struct Curl_multi *)multi_handle,
                       TRUE, CURL_SOCKET_BAD, running_handles);
+  if (CURLM_OK == result)
+    update_timer((struct Curl_multi *)multi_handle);
+  return result;
 }
 
 CURLMcode curl_multi_timeout(CURLM *multi_handle,
@@ -1722,6 +1747,23 @@
   return CURLM_OK;
 }
 
+/* 
+  A preliminary shot at the timer callback invocation. This
+  needs to be called at various places in the library code,
+  to tell the application it should update its timers.
+*/
+static int update_timer(struct Curl_multi *multi)
+{
+  long timeout_ms;
+  if (!multi->timer_cb)
+    return 0;
+  if ( curl_multi_timeout(multi, &timeout_ms) != CURLM_OK )
+    return -1;
+  if ( timeout_ms < 0 )
+    return 0;
+  return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
+}
+
 /* given a number of milliseconds from now to use to set the 'act before
    this'-time for the transfer, to be extracted by curl_multi_timeout() */
 void Curl_expire(struct SessionHandle *data, long milli)
