multi.c: OOM handling fix
[platform/upstream/curl.git] / lib / multi.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22
23 #include "setup.h"
24
25 #include <curl/curl.h>
26
27 #include "urldata.h"
28 #include "transfer.h"
29 #include "url.h"
30 #include "connect.h"
31 #include "progress.h"
32 #include "easyif.h"
33 #include "multiif.h"
34 #include "sendf.h"
35 #include "timeval.h"
36 #include "http.h"
37 #include "select.h"
38 #include "warnless.h"
39 #include "speedcheck.h"
40 #include "conncache.h"
41 #include "bundles.h"
42
43 #define _MPRINTF_REPLACE /* use our functions only */
44 #include <curl/mprintf.h>
45
46 #include "curl_memory.h"
47 /* The last #include file should be: */
48 #include "memdebug.h"
49
50 /*
51   CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
52   to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes.  Still, every
53   CURL handle takes 45-50 K memory, therefore this 3K are not significant.
54 */
55 #ifndef CURL_SOCKET_HASH_TABLE_SIZE
56 #define CURL_SOCKET_HASH_TABLE_SIZE 911
57 #endif
58
59 struct Curl_message {
60   /* the 'CURLMsg' is the part that is visible to the external user */
61   struct CURLMsg extmsg;
62 };
63
64 /* NOTE: if you add a state here, add the name to the statename[] array as
65    well!
66 */
67 typedef enum {
68   CURLM_STATE_INIT,        /* 0 - start in this state */
69   CURLM_STATE_CONNECT,     /* 1 - resolve/connect has been sent off */
70   CURLM_STATE_WAITRESOLVE, /* 2 - awaiting the resolve to finalize */
71   CURLM_STATE_WAITCONNECT, /* 3 - awaiting the connect to finalize */
72   CURLM_STATE_WAITPROXYCONNECT, /* 4 - awaiting proxy CONNECT to finalize */
73   CURLM_STATE_PROTOCONNECT, /* 5 - completing the protocol-specific connect
74                                phase */
75   CURLM_STATE_WAITDO,      /* 6 - wait for our turn to send the request */
76   CURLM_STATE_DO,          /* 7 - start send off the request (part 1) */
77   CURLM_STATE_DOING,       /* 8 - sending off the request (part 1) */
78   CURLM_STATE_DO_MORE,     /* 9 - send off the request (part 2) */
79   CURLM_STATE_DO_DONE,     /* 10 - done sending off request */
80   CURLM_STATE_WAITPERFORM, /* 11 - wait for our turn to read the response */
81   CURLM_STATE_PERFORM,     /* 12 - transfer data */
82   CURLM_STATE_TOOFAST,     /* 13 - wait because limit-rate exceeded */
83   CURLM_STATE_DONE,        /* 14 - post data transfer operation */
84   CURLM_STATE_COMPLETED,   /* 15 - operation complete */
85   CURLM_STATE_MSGSENT,     /* 16 - the operation complete message is sent */
86   CURLM_STATE_LAST         /* 17 - not a true state, never use this */
87 } CURLMstate;
88
89 /* we support N sockets per easy handle. Set the corresponding bit to what
90    action we should wait for */
91 #define MAX_SOCKSPEREASYHANDLE 5
92 #define GETSOCK_READABLE (0x00ff)
93 #define GETSOCK_WRITABLE (0xff00)
94
95 struct Curl_one_easy {
96   /* first, two fields for the linked list of these */
97   struct Curl_one_easy *next;
98   struct Curl_one_easy *prev;
99
100   struct SessionHandle *easy_handle; /* the easy handle for this unit */
101   struct connectdata *easy_conn;     /* the "unit's" connection */
102
103   CURLMstate state;  /* the handle's state */
104   CURLcode result;   /* previous result */
105
106   struct Curl_message msg; /* A single posted message. */
107
108   /* Array with the plain socket numbers this handle takes care of, in no
109      particular order. Note that all sockets are added to the sockhash, where
110      the state etc are also kept. This array is mostly used to detect when a
111      socket is to be removed from the hash. See singlesocket(). */
112   curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
113   int numsocks;
114 };
115
116 #define CURL_MULTI_HANDLE 0x000bab1e
117
118 #define GOOD_MULTI_HANDLE(x) \
119   ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
120 #define GOOD_EASY_HANDLE(x) \
121   ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
122
123 /* This is the struct known as CURLM on the outside */
124 struct Curl_multi {
125   /* First a simple identifier to easier detect if a user mix up
126      this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
127   long type;
128
129   /* We have a doubly-linked circular list with easy handles */
130   struct Curl_one_easy easy;
131
132   int num_easy; /* amount of entries in the linked list above. */
133   int num_alive; /* amount of easy handles that are added but have not yet
134                     reached COMPLETE state */
135
136   struct curl_llist *msglist; /* a list of messages from completed transfers */
137
138   /* callback function and user data pointer for the *socket() API */
139   curl_socket_callback socket_cb;
140   void *socket_userp;
141
142   /* Hostname cache */
143   struct curl_hash *hostcache;
144
145   /* timetree points to the splay-tree of time nodes to figure out expire
146      times of all currently set timers */
147   struct Curl_tree *timetree;
148
149   /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
150      the pluralis form, there can be more than one easy handle waiting on the
151      same actual socket) */
152   struct curl_hash *sockhash;
153
154   /* Whether pipelining is enabled for this multi handle */
155   bool pipelining_enabled;
156
157   /* Shared connection cache (bundles)*/
158   struct conncache *conn_cache;
159
160   /* This handle will be used for closing the cached connections in
161      curl_multi_cleanup() */
162   struct SessionHandle *closure_handle;
163
164   long maxconnects; /* if >0, a fixed limit of the maximum number of entries
165                        we're allowed to grow the connection cache to */
166
167   /* timer callback and user data pointer for the *socket() API */
168   curl_multi_timer_callback timer_cb;
169   void *timer_userp;
170   struct timeval timer_lastcall; /* the fixed time for the timeout for the
171                                     previous callback */
172 };
173
174 static void singlesocket(struct Curl_multi *multi,
175                          struct Curl_one_easy *easy);
176 static int update_timer(struct Curl_multi *multi);
177
178 static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
179                                               struct connectdata *conn);
180 static int checkPendPipeline(struct connectdata *conn);
181 static void moveHandleFromSendToRecvPipeline(struct SessionHandle *handle,
182                                              struct connectdata *conn);
183 static void moveHandleFromRecvToDonePipeline(struct SessionHandle *handle,
184                                              struct connectdata *conn);
185 static bool isHandleAtHead(struct SessionHandle *handle,
186                            struct curl_llist *pipeline);
187 static CURLMcode add_next_timeout(struct timeval now,
188                                   struct Curl_multi *multi,
189                                   struct SessionHandle *d);
190
191 #ifdef DEBUGBUILD
192 static const char * const statename[]={
193   "INIT",
194   "CONNECT",
195   "WAITRESOLVE",
196   "WAITCONNECT",
197   "WAITPROXYCONNECT",
198   "PROTOCONNECT",
199   "WAITDO",
200   "DO",
201   "DOING",
202   "DO_MORE",
203   "DO_DONE",
204   "WAITPERFORM",
205   "PERFORM",
206   "TOOFAST",
207   "DONE",
208   "COMPLETED",
209   "MSGSENT",
210 };
211 #endif
212
213 static void multi_freetimeout(void *a, void *b);
214
215 /* always use this function to change state, to make debugging easier */
216 static void multistate(struct Curl_one_easy *easy, CURLMstate state)
217 {
218 #ifdef DEBUGBUILD
219   long connection_id = -5000;
220 #endif
221   CURLMstate oldstate = easy->state;
222
223   if(oldstate == state)
224     /* don't bother when the new state is the same as the old state */
225     return;
226
227   easy->state = state;
228
229 #ifdef DEBUGBUILD
230   if(easy->easy_conn) {
231     if(easy->state > CURLM_STATE_CONNECT &&
232        easy->state < CURLM_STATE_COMPLETED)
233       connection_id = easy->easy_conn->connection_id;
234
235     infof(easy->easy_handle,
236           "STATE: %s => %s handle %p; (connection #%ld) \n",
237           statename[oldstate], statename[easy->state],
238           (char *)easy, connection_id);
239   }
240 #endif
241   if(state == CURLM_STATE_COMPLETED)
242     /* changing to COMPLETED means there's one less easy handle 'alive' */
243     easy->easy_handle->multi->num_alive--;
244 }
245
246 /*
247  * We add one of these structs to the sockhash for a particular socket
248  */
249
250 struct Curl_sh_entry {
251   struct SessionHandle *easy;
252   time_t timestamp;
253   int action;  /* what action READ/WRITE this socket waits for */
254   curl_socket_t socket; /* mainly to ease debugging */
255   void *socketp; /* settable by users with curl_multi_assign() */
256 };
257 /* bits for 'action' having no bits means this socket is not expecting any
258    action */
259 #define SH_READ  1
260 #define SH_WRITE 2
261
262 /* make sure this socket is present in the hash for this handle */
263 static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
264                                          curl_socket_t s,
265                                          struct SessionHandle *data)
266 {
267   struct Curl_sh_entry *there =
268     Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
269   struct Curl_sh_entry *check;
270
271   if(there)
272     /* it is present, return fine */
273     return there;
274
275   /* not present, add it */
276   check = calloc(1, sizeof(struct Curl_sh_entry));
277   if(!check)
278     return NULL; /* major failure */
279   check->easy = data;
280   check->socket = s;
281
282   /* make/add new hash entry */
283   if(NULL == Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
284     free(check);
285     return NULL; /* major failure */
286   }
287
288   return check; /* things are good in sockhash land */
289 }
290
291
292 /* delete the given socket + handle from the hash */
293 static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
294 {
295   struct Curl_sh_entry *there =
296     Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
297
298   if(there) {
299     /* this socket is in the hash */
300     /* We remove the hash entry. (This'll end up in a call to
301        sh_freeentry().) */
302     Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
303   }
304 }
305
306 /*
307  * free a sockhash entry
308  */
309 static void sh_freeentry(void *freethis)
310 {
311   struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
312
313   if(p)
314     free(p);
315 }
316
317 static size_t fd_key_compare(void*k1, size_t k1_len, void*k2, size_t k2_len)
318 {
319   (void) k1_len; (void) k2_len;
320
321   return (*((int* ) k1)) == (*((int* ) k2));
322 }
323
324 static size_t hash_fd(void* key, size_t key_length, size_t slots_num)
325 {
326   int fd = * ((int* ) key);
327   (void) key_length;
328
329   return (fd % (int)slots_num);
330 }
331
332 /*
333  * sh_init() creates a new socket hash and returns the handle for it.
334  *
335  * Quote from README.multi_socket:
336  *
337  * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
338  * is somewhat of a bottle neck. Its current implementation may be a bit too
339  * limiting. It simply has a fixed-size array, and on each entry in the array
340  * it has a linked list with entries. So the hash only checks which list to
341  * scan through. The code I had used so for used a list with merely 7 slots
342  * (as that is what the DNS hash uses) but with 7000 connections that would
343  * make an average of 1000 nodes in each list to run through. I upped that to
344  * 97 slots (I believe a prime is suitable) and noticed a significant speed
345  * increase.  I need to reconsider the hash implementation or use a rather
346  * large default value like this. At 9000 connections I was still below 10us
347  * per call."
348  *
349  */
350 static struct curl_hash *sh_init(void)
351 {
352   return Curl_hash_alloc(CURL_SOCKET_HASH_TABLE_SIZE, hash_fd, fd_key_compare,
353                          sh_freeentry);
354 }
355
356 /*
357  * multi_addmsg()
358  *
359  * Called when a transfer is completed. Adds the given msg pointer to
360  * the list kept in the multi handle.
361  */
362 static CURLMcode multi_addmsg(struct Curl_multi *multi,
363                               struct Curl_message *msg)
364 {
365   if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
366     return CURLM_OUT_OF_MEMORY;
367
368   return CURLM_OK;
369 }
370
371 /*
372  * multi_freeamsg()
373  *
374  * Callback used by the llist system when a single list entry is destroyed.
375  */
376 static void multi_freeamsg(void *a, void *b)
377 {
378   (void)a;
379   (void)b;
380 }
381
382 CURLM *curl_multi_init(void)
383 {
384   struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
385
386   if(!multi)
387     return NULL;
388
389   multi->type = CURL_MULTI_HANDLE;
390
391   multi->hostcache = Curl_mk_dnscache();
392   if(!multi->hostcache)
393     goto error;
394
395   multi->sockhash = sh_init();
396   if(!multi->sockhash)
397     goto error;
398
399   multi->conn_cache = Curl_conncache_init(CONNCACHE_MULTI);
400   if(!multi->conn_cache)
401     goto error;
402
403   multi->msglist = Curl_llist_alloc(multi_freeamsg);
404   if(!multi->msglist)
405     goto error;
406
407   /* Let's make the doubly-linked list a circular list.  This makes
408      the linked list code simpler and allows inserting at the end
409      with less work (we didn't keep a tail pointer before). */
410   multi->easy.next = &multi->easy;
411   multi->easy.prev = &multi->easy;
412
413   return (CURLM *) multi;
414
415   error:
416
417   Curl_hash_destroy(multi->sockhash);
418   multi->sockhash = NULL;
419   Curl_hash_destroy(multi->hostcache);
420   multi->hostcache = NULL;
421   Curl_conncache_destroy(multi->conn_cache);
422   multi->conn_cache = NULL;
423
424   free(multi);
425   return NULL;
426 }
427
428 CURLMcode curl_multi_add_handle(CURLM *multi_handle,
429                                 CURL *easy_handle)
430 {
431   struct curl_llist *timeoutlist;
432   struct Curl_one_easy *easy;
433   struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
434   struct SessionHandle *data = (struct SessionHandle *)easy_handle;
435   struct SessionHandle *new_closure = NULL;
436
437   /* First, make some basic checks that the CURLM handle is a good handle */
438   if(!GOOD_MULTI_HANDLE(multi))
439     return CURLM_BAD_HANDLE;
440
441   /* Verify that we got a somewhat good easy handle too */
442   if(!GOOD_EASY_HANDLE(easy_handle))
443     return CURLM_BAD_EASY_HANDLE;
444
445   /* Prevent users from adding same easy handle more than
446      once and prevent adding to more than one multi stack */
447   if(data->multi)
448     /* possibly we should create a new unique error code for this condition */
449     return CURLM_BAD_EASY_HANDLE;
450
451   /* Allocate and initialize timeout list for easy handle */
452   timeoutlist = Curl_llist_alloc(multi_freetimeout);
453   if(!timeoutlist)
454     return CURLM_OUT_OF_MEMORY;
455
456   /* Allocate new node for the doubly-linked circular list of
457      Curl_one_easy structs that holds pointers to easy handles */
458   easy = calloc(1, sizeof(struct Curl_one_easy));
459   if(!easy) {
460     Curl_llist_destroy(timeoutlist, NULL);
461     return CURLM_OUT_OF_MEMORY;
462   }
463
464   /* In case multi handle has no closure_handle yet, allocate
465      a new easy handle to use when closing cached connections */
466   if(!multi->closure_handle) {
467     new_closure = (struct SessionHandle *)curl_easy_init();
468     if(!new_closure) {
469       free(easy);
470       Curl_llist_destroy(timeoutlist, NULL);
471       return CURLM_OUT_OF_MEMORY;
472     }
473   }
474
475   /*
476   ** No failure allowed in this function beyond this point. And
477   ** no modification of easy nor multi handle allowed before this
478   ** except for potential multi's connection cache growing which
479   ** won't be undone in this function no matter what.
480   */
481
482   /* In case a new closure handle has been initialized above, it
483      is associated now with the multi handle which lacked one. */
484   if(new_closure) {
485     multi->closure_handle = new_closure;
486     Curl_easy_addmulti(multi->closure_handle, multi_handle);
487     multi->closure_handle->state.conn_cache = multi->conn_cache;
488   }
489
490   /* Make easy handle use timeout list initialized above */
491   data->state.timeoutlist = timeoutlist;
492   timeoutlist = NULL;
493
494   /* set the easy handle */
495   easy->easy_handle = data;
496   multistate(easy, CURLM_STATE_INIT);
497
498   /* set the back pointer to one_easy to assist in removal */
499   easy->easy_handle->multi_pos =  easy;
500
501   /* for multi interface connections, we share DNS cache automatically if the
502      easy handle's one is currently private. */
503   if(easy->easy_handle->dns.hostcache &&
504      (easy->easy_handle->dns.hostcachetype == HCACHE_PRIVATE)) {
505     Curl_hash_destroy(easy->easy_handle->dns.hostcache);
506     easy->easy_handle->dns.hostcache = NULL;
507     easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
508   }
509
510   if(!easy->easy_handle->dns.hostcache ||
511      (easy->easy_handle->dns.hostcachetype == HCACHE_NONE)) {
512     easy->easy_handle->dns.hostcache = multi->hostcache;
513     easy->easy_handle->dns.hostcachetype = HCACHE_MULTI;
514   }
515
516   /* On a multi stack the connection cache, owned by the multi handle,
517      is shared between all easy handles within the multi handle.
518      Therefore we free the private connection cache if there is one */
519   if(easy->easy_handle->state.conn_cache &&
520      easy->easy_handle->state.conn_cache->type == CONNCACHE_PRIVATE) {
521     Curl_conncache_destroy(easy->easy_handle->state.conn_cache);
522   }
523
524   /* Point now to this multi's connection cache */
525   easy->easy_handle->state.conn_cache = multi->conn_cache;
526
527   /* This adds the new entry at the 'end' of the doubly-linked circular
528      list of Curl_one_easy structs to try and maintain a FIFO queue so
529      the pipelined requests are in order. */
530
531   /* We add this new entry last in the list. We make our 'next' point to the
532      'first' struct and our 'prev' point to the previous 'prev' */
533   easy->next = &multi->easy;
534   easy->prev = multi->easy.prev;
535
536   /* make 'easy' the last node in the chain */
537   multi->easy.prev = easy;
538
539   /* if there was a prev node, make sure its 'next' pointer links to
540      the new node */
541   easy->prev->next = easy;
542
543   /* make the SessionHandle refer back to this multi handle */
544   Curl_easy_addmulti(easy_handle, multi_handle);
545
546   /* make the SessionHandle struct refer back to this struct */
547   easy->easy_handle->set.one_easy = easy;
548
549   /* Set the timeout for this handle to expire really soon so that it will
550      be taken care of even when this handle is added in the midst of operation
551      when only the curl_multi_socket() API is used. During that flow, only
552      sockets that time-out or have actions will be dealt with. Since this
553      handle has no action yet, we make sure it times out to get things to
554      happen. */
555   Curl_expire(easy->easy_handle, 1);
556
557   /* increase the node-counter */
558   multi->num_easy++;
559
560   /* increase the alive-counter */
561   multi->num_alive++;
562
563   /* A somewhat crude work-around for a little glitch in update_timer() that
564      happens if the lastcall time is set to the same time when the handle is
565      removed as when the next handle is added, as then the check in
566      update_timer() that prevents calling the application multiple times with
567      the same timer infor will not trigger and then the new handle's timeout
568      will not be notified to the app.
569
570      The work-around is thus simply to clear the 'lastcall' variable to force
571      update_timer() to always trigger a callback to the app when a new easy
572      handle is added */
573   memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
574
575   update_timer(multi);
576   return CURLM_OK;
577 }
578
579 #if 0
580 /* Debug-function, used like this:
581  *
582  * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
583  *
584  * Enable the hash print function first by editing hash.c
585  */
586 static void debug_print_sock_hash(void *p)
587 {
588   struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
589
590   fprintf(stderr, " [easy %p/magic %x/socket %d]",
591           (void *)sh->easy, sh->easy->magic, (int)sh->socket);
592 }
593 #endif
594
595 CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
596                                    CURL *curl_handle)
597 {
598   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
599   struct Curl_one_easy *easy;
600   struct SessionHandle *data = curl_handle;
601
602   /* First, make some basic checks that the CURLM handle is a good handle */
603   if(!GOOD_MULTI_HANDLE(multi))
604     return CURLM_BAD_HANDLE;
605
606   /* Verify that we got a somewhat good easy handle too */
607   if(!GOOD_EASY_HANDLE(curl_handle))
608     return CURLM_BAD_EASY_HANDLE;
609
610   /* pick-up from the 'curl_handle' the kept position in the list */
611   easy = data->multi_pos;
612
613   if(easy) {
614     bool premature = (easy->state < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
615     bool easy_owns_conn = (easy->easy_conn &&
616                            (easy->easy_conn->data == easy->easy_handle)) ?
617                            TRUE : FALSE;
618
619     /* If the 'state' is not INIT or COMPLETED, we might need to do something
620        nice to put the easy_handle in a good known state when this returns. */
621     if(premature)
622       /* this handle is "alive" so we need to count down the total number of
623          alive connections when this is removed */
624       multi->num_alive--;
625
626     if(easy->easy_conn &&
627        (easy->easy_conn->send_pipe->size +
628         easy->easy_conn->recv_pipe->size > 1) &&
629        easy->state > CURLM_STATE_WAITDO &&
630        easy->state < CURLM_STATE_COMPLETED) {
631       /* If the handle is in a pipeline and has started sending off its
632          request but not received its response yet, we need to close
633          connection. */
634       easy->easy_conn->bits.close = TRUE;
635       /* Set connection owner so that Curl_done() closes it.
636          We can sefely do this here since connection is killed. */
637       easy->easy_conn->data = easy->easy_handle;
638     }
639
640     /* The timer must be shut down before easy->multi is set to NULL,
641        else the timenode will remain in the splay tree after
642        curl_easy_cleanup is called. */
643     Curl_expire(easy->easy_handle, 0);
644
645     /* destroy the timeout list that is held in the easy handle */
646     if(data->state.timeoutlist) {
647       Curl_llist_destroy(data->state.timeoutlist, NULL);
648       data->state.timeoutlist = NULL;
649     }
650
651     if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
652       /* clear out the usage of the shared DNS cache */
653       easy->easy_handle->dns.hostcache = NULL;
654       easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
655     }
656
657     if(easy->easy_conn) {
658
659       /* we must call Curl_done() here (if we still "own it") so that we don't
660          leave a half-baked one around */
661       if(easy_owns_conn) {
662
663         /* Curl_done() clears the conn->data field to lose the association
664            between the easy handle and the connection
665
666            Note that this ignores the return code simply because there's
667            nothing really useful to do with it anyway! */
668         (void)Curl_done(&easy->easy_conn, easy->result, premature);
669       }
670       else
671         /* Clear connection pipelines, if Curl_done above was not called */
672         Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
673     }
674
675     if(easy->easy_handle->state.conn_cache->type == CONNCACHE_MULTI) {
676       /* if this was using the shared connection cache we clear the pointer
677          to that since we're not part of that handle anymore */
678       easy->easy_handle->state.conn_cache = NULL;
679       easy->easy_handle->state.lastconnect = NULL;
680     }
681
682     /* change state without using multistate(), only to make singlesocket() do
683        what we want */
684     easy->state = CURLM_STATE_COMPLETED;
685     singlesocket(multi, easy); /* to let the application know what sockets
686                                   that vanish with this handle */
687
688     /* Remove the association between the connection and the handle */
689     if(easy->easy_conn) {
690       easy->easy_conn->data = NULL;
691       easy->easy_conn = NULL;
692     }
693
694     Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association
695                                                     to this multi handle */
696
697     {
698       /* make sure there's no pending message in the queue sent from this easy
699          handle */
700       struct curl_llist_element *e;
701
702       for(e = multi->msglist->head; e; e = e->next) {
703         struct Curl_message *msg = e->ptr;
704
705         if(msg->extmsg.easy_handle == easy->easy_handle) {
706           Curl_llist_remove(multi->msglist, e, NULL);
707           /* there can only be one from this specific handle */
708           break;
709         }
710       }
711     }
712
713     /* make the previous node point to our next */
714     if(easy->prev)
715       easy->prev->next = easy->next;
716     /* make our next point to our previous node */
717     if(easy->next)
718       easy->next->prev = easy->prev;
719
720     easy->easy_handle->set.one_easy = NULL; /* detached */
721
722     /* Null the position in the controlling structure */
723     easy->easy_handle->multi_pos = NULL;
724
725     /* NOTE NOTE NOTE
726        We do not touch the easy handle here! */
727     free(easy);
728
729     multi->num_easy--; /* one less to care about now */
730
731     update_timer(multi);
732     return CURLM_OK;
733   }
734   else
735     return CURLM_BAD_EASY_HANDLE; /* twasn't found */
736 }
737
738 bool Curl_multi_canPipeline(const struct Curl_multi* multi)
739 {
740   return multi->pipelining_enabled;
741 }
742
743 void Curl_multi_handlePipeBreak(struct SessionHandle *data)
744 {
745   struct Curl_one_easy *one_easy = data->set.one_easy;
746
747   if(one_easy)
748     one_easy->easy_conn = NULL;
749 }
750
751 static int waitconnect_getsock(struct connectdata *conn,
752                                curl_socket_t *sock,
753                                int numsocks)
754 {
755   if(!numsocks)
756     return GETSOCK_BLANK;
757
758   sock[0] = conn->sock[FIRSTSOCKET];
759
760   /* when we've sent a CONNECT to a proxy, we should rather wait for the
761      socket to become readable to be able to get the response headers */
762   if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
763     return GETSOCK_READSOCK(0);
764
765   return GETSOCK_WRITESOCK(0);
766 }
767
768 static int domore_getsock(struct connectdata *conn,
769                           curl_socket_t *socks,
770                           int numsocks)
771 {
772   if(conn && conn->handler->domore_getsock)
773     return conn->handler->domore_getsock(conn, socks, numsocks);
774   return GETSOCK_BLANK;
775 }
776
777 /* returns bitmapped flags for this handle and its sockets */
778 static int multi_getsock(struct Curl_one_easy *easy,
779                          curl_socket_t *socks, /* points to numsocks number
780                                                   of sockets */
781                          int numsocks)
782 {
783   /* If the pipe broke, or if there's no connection left for this easy handle,
784      then we MUST bail out now with no bitmask set. The no connection case can
785      happen when this is called from curl_multi_remove_handle() =>
786      singlesocket() => multi_getsock().
787   */
788   if(easy->easy_handle->state.pipe_broke || !easy->easy_conn)
789     return 0;
790
791   if(easy->state > CURLM_STATE_CONNECT &&
792      easy->state < CURLM_STATE_COMPLETED) {
793     /* Set up ownership correctly */
794     easy->easy_conn->data = easy->easy_handle;
795   }
796
797   switch(easy->state) {
798   default:
799 #if 0 /* switch back on these cases to get the compiler to check for all enums
800          to be present */
801   case CURLM_STATE_TOOFAST:  /* returns 0, so will not select. */
802   case CURLM_STATE_COMPLETED:
803   case CURLM_STATE_MSGSENT:
804   case CURLM_STATE_INIT:
805   case CURLM_STATE_CONNECT:
806   case CURLM_STATE_WAITDO:
807   case CURLM_STATE_DONE:
808   case CURLM_STATE_LAST:
809     /* this will get called with CURLM_STATE_COMPLETED when a handle is
810        removed */
811 #endif
812     return 0;
813
814   case CURLM_STATE_WAITRESOLVE:
815     return Curl_resolver_getsock(easy->easy_conn, socks, numsocks);
816
817   case CURLM_STATE_PROTOCONNECT:
818     return Curl_protocol_getsock(easy->easy_conn, socks, numsocks);
819
820   case CURLM_STATE_DO:
821   case CURLM_STATE_DOING:
822     return Curl_doing_getsock(easy->easy_conn, socks, numsocks);
823
824   case CURLM_STATE_WAITPROXYCONNECT:
825   case CURLM_STATE_WAITCONNECT:
826     return waitconnect_getsock(easy->easy_conn, socks, numsocks);
827
828   case CURLM_STATE_DO_MORE:
829     return domore_getsock(easy->easy_conn, socks, numsocks);
830
831   case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
832                                to waiting for the same as the *PERFORM
833                                states */
834   case CURLM_STATE_PERFORM:
835   case CURLM_STATE_WAITPERFORM:
836     return Curl_single_getsock(easy->easy_conn, socks, numsocks);
837   }
838
839 }
840
841 CURLMcode curl_multi_fdset(CURLM *multi_handle,
842                            fd_set *read_fd_set, fd_set *write_fd_set,
843                            fd_set *exc_fd_set, int *max_fd)
844 {
845   /* Scan through all the easy handles to get the file descriptors set.
846      Some easy handles may not have connected to the remote host yet,
847      and then we must make sure that is done. */
848   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
849   struct Curl_one_easy *easy;
850   int this_max_fd=-1;
851   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
852   int bitmap;
853   int i;
854   (void)exc_fd_set; /* not used */
855
856   if(!GOOD_MULTI_HANDLE(multi))
857     return CURLM_BAD_HANDLE;
858
859   easy=multi->easy.next;
860   while(easy != &multi->easy) {
861     bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
862
863     for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
864       curl_socket_t s = CURL_SOCKET_BAD;
865
866       if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
867         FD_SET(sockbunch[i], read_fd_set);
868         s = sockbunch[i];
869       }
870       if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
871         FD_SET(sockbunch[i], write_fd_set);
872         s = sockbunch[i];
873       }
874       if(s == CURL_SOCKET_BAD)
875         /* this socket is unused, break out of loop */
876         break;
877       else {
878         if((int)s > this_max_fd)
879           this_max_fd = (int)s;
880       }
881     }
882
883     easy = easy->next; /* check next handle */
884   }
885
886   *max_fd = this_max_fd;
887
888   return CURLM_OK;
889 }
890
891 CURLMcode curl_multi_wait(CURLM *multi_handle,
892                           struct curl_waitfd extra_fds[],
893                           unsigned int extra_nfds,
894                           int timeout_ms,
895                           int *ret)
896 {
897   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
898   struct Curl_one_easy *easy;
899   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
900   int bitmap;
901   unsigned int i;
902   unsigned int nfds = extra_nfds;
903   struct pollfd *ufds;
904
905   if(!GOOD_MULTI_HANDLE(multi))
906     return CURLM_BAD_HANDLE;
907
908   /* Count up how many fds we have from the multi handle */
909   easy=multi->easy.next;
910   while(easy != &multi->easy) {
911     bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
912
913     for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
914       curl_socket_t s = CURL_SOCKET_BAD;
915
916       if(bitmap & GETSOCK_READSOCK(i)) {
917         ++nfds;
918         s = sockbunch[i];
919       }
920       if(bitmap & GETSOCK_WRITESOCK(i)) {
921         ++nfds;
922         s = sockbunch[i];
923       }
924       if(s == CURL_SOCKET_BAD) {
925         break;
926       }
927     }
928
929     easy = easy->next; /* check next handle */
930   }
931
932   ufds = (struct pollfd *)malloc(nfds * sizeof(struct pollfd));
933   nfds = 0;
934
935   /* Add the curl handles to our pollfds first */
936   easy=multi->easy.next;
937   while(easy != &multi->easy) {
938     bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
939
940     for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
941       curl_socket_t s = CURL_SOCKET_BAD;
942
943       if(bitmap & GETSOCK_READSOCK(i)) {
944         ufds[nfds].fd = sockbunch[i];
945         ufds[nfds].events = POLLIN;
946         ++nfds;
947         s = sockbunch[i];
948       }
949       if(bitmap & GETSOCK_WRITESOCK(i)) {
950         ufds[nfds].fd = sockbunch[i];
951         ufds[nfds].events = POLLOUT;
952         ++nfds;
953         s = sockbunch[i];
954       }
955       if(s == CURL_SOCKET_BAD) {
956         break;
957       }
958     }
959
960     easy = easy->next; /* check next handle */
961   }
962
963   /* Add external file descriptions from poll-like struct curl_waitfd */
964   for(i = 0; i < extra_nfds; i++) {
965     ufds[nfds].fd = extra_fds[i].fd;
966     ufds[nfds].events = 0;
967     if(extra_fds[i].events & CURL_WAIT_POLLIN)
968       ufds[nfds].events |= POLLIN;
969     if(extra_fds[i].events & CURL_WAIT_POLLPRI)
970       ufds[nfds].events |= POLLPRI;
971     if(extra_fds[i].events & CURL_WAIT_POLLOUT)
972       ufds[nfds].events |= POLLOUT;
973     ++nfds;
974   }
975
976   if(nfds)
977     /* wait... */
978     i = Curl_poll(ufds, nfds, timeout_ms);
979   else
980     i = 0;
981
982   free(ufds);
983   if(ret)
984     *ret = i;
985   return CURLM_OK;
986 }
987
988 static CURLMcode multi_runsingle(struct Curl_multi *multi,
989                                  struct timeval now,
990                                  struct Curl_one_easy *easy)
991 {
992   struct Curl_message *msg = NULL;
993   bool connected;
994   bool async;
995   bool protocol_connect = FALSE;
996   bool dophase_done;
997   bool done = FALSE;
998   CURLMcode result = CURLM_OK;
999   struct SingleRequest *k;
1000   struct SessionHandle *data;
1001   long timeout_ms;
1002
1003   if(!GOOD_EASY_HANDLE(easy->easy_handle))
1004     return CURLM_BAD_EASY_HANDLE;
1005
1006   data = easy->easy_handle;
1007
1008   do {
1009     /* this is a single-iteration do-while loop just to allow a
1010        break to skip to the end of it */
1011     bool disconnect_conn = FALSE;
1012
1013     /* Handle the case when the pipe breaks, i.e., the connection
1014        we're using gets cleaned up and we're left with nothing. */
1015     if(data->state.pipe_broke) {
1016       infof(data, "Pipe broke: handle 0x%p, url = %s\n",
1017             easy, data->state.path);
1018
1019       if(easy->state < CURLM_STATE_COMPLETED) {
1020         /* Head back to the CONNECT state */
1021         multistate(easy, CURLM_STATE_CONNECT);
1022         result = CURLM_CALL_MULTI_PERFORM;
1023         easy->result = CURLE_OK;
1024       }
1025
1026       data->state.pipe_broke = FALSE;
1027       easy->easy_conn = NULL;
1028       break;
1029     }
1030
1031     if(!easy->easy_conn &&
1032        easy->state > CURLM_STATE_CONNECT &&
1033        easy->state < CURLM_STATE_DONE) {
1034       /* In all these states, the code will blindly access 'easy->easy_conn'
1035          so this is precaution that it isn't NULL. And it silences static
1036          analyzers. */
1037       failf(data, "In state %d with no easy_conn, bail out!\n", easy->state);
1038       return CURLM_INTERNAL_ERROR;
1039     }
1040
1041     if(easy->easy_conn && easy->state > CURLM_STATE_CONNECT &&
1042        easy->state < CURLM_STATE_COMPLETED)
1043       /* Make sure we set the connection's current owner */
1044       easy->easy_conn->data = data;
1045
1046     if(easy->easy_conn &&
1047        (easy->state >= CURLM_STATE_CONNECT) &&
1048        (easy->state < CURLM_STATE_COMPLETED)) {
1049       /* we need to wait for the connect state as only then is the start time
1050          stored, but we must not check already completed handles */
1051
1052       timeout_ms = Curl_timeleft(data, &now,
1053                                  (easy->state <= CURLM_STATE_WAITDO)?
1054                                  TRUE:FALSE);
1055
1056       if(timeout_ms < 0) {
1057         /* Handle timed out */
1058         if(easy->state == CURLM_STATE_WAITRESOLVE)
1059           failf(data, "Resolving timed out after %ld milliseconds",
1060                 Curl_tvdiff(now, data->progress.t_startsingle));
1061         else if(easy->state == CURLM_STATE_WAITCONNECT)
1062           failf(data, "Connection timed out after %ld milliseconds",
1063                 Curl_tvdiff(now, data->progress.t_startsingle));
1064         else {
1065           k = &data->req;
1066           failf(data, "Operation timed out after %ld milliseconds with %"
1067                 FORMAT_OFF_T " out of %" FORMAT_OFF_T " bytes received",
1068                 Curl_tvdiff(now, data->progress.t_startsingle), k->bytecount,
1069                 k->size);
1070         }
1071
1072         /* Force the connection closed because the server could continue to
1073            send us stuff at any time. (The disconnect_conn logic used below
1074            doesn't work at this point). */
1075         easy->easy_conn->bits.close = TRUE;
1076         easy->result = CURLE_OPERATION_TIMEDOUT;
1077         multistate(easy, CURLM_STATE_COMPLETED);
1078         break;
1079       }
1080     }
1081
1082     switch(easy->state) {
1083     case CURLM_STATE_INIT:
1084       /* init this transfer. */
1085       easy->result=Curl_pretransfer(data);
1086
1087       if(CURLE_OK == easy->result) {
1088         /* after init, go CONNECT */
1089         multistate(easy, CURLM_STATE_CONNECT);
1090         result = CURLM_CALL_MULTI_PERFORM;
1091
1092         data->state.used_interface = Curl_if_multi;
1093       }
1094       break;
1095
1096     case CURLM_STATE_CONNECT:
1097       /* Connect. We get a connection identifier filled in. */
1098       Curl_pgrsTime(data, TIMER_STARTSINGLE);
1099       easy->result = Curl_connect(data, &easy->easy_conn,
1100                                   &async, &protocol_connect);
1101
1102       if(CURLE_OK == easy->result) {
1103         /* Add this handle to the send or pend pipeline */
1104         easy->result = addHandleToSendOrPendPipeline(data,
1105                                                      easy->easy_conn);
1106         if(CURLE_OK != easy->result)
1107           disconnect_conn = TRUE;
1108         else {
1109           if(async)
1110             /* We're now waiting for an asynchronous name lookup */
1111             multistate(easy, CURLM_STATE_WAITRESOLVE);
1112           else {
1113             /* after the connect has been sent off, go WAITCONNECT unless the
1114                protocol connect is already done and we can go directly to
1115                WAITDO or DO! */
1116             result = CURLM_CALL_MULTI_PERFORM;
1117
1118             if(protocol_connect)
1119               multistate(easy, multi->pipelining_enabled?
1120                          CURLM_STATE_WAITDO:CURLM_STATE_DO);
1121             else {
1122 #ifndef CURL_DISABLE_HTTP
1123               if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1124                 multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1125               else
1126 #endif
1127                 multistate(easy, CURLM_STATE_WAITCONNECT);
1128             }
1129           }
1130         }
1131       }
1132       break;
1133
1134     case CURLM_STATE_WAITRESOLVE:
1135       /* awaiting an asynch name resolve to complete */
1136     {
1137       struct Curl_dns_entry *dns = NULL;
1138
1139       /* check if we have the name resolved by now */
1140       easy->result = Curl_resolver_is_resolved(easy->easy_conn, &dns);
1141
1142       /* Update sockets here, because the socket(s) may have been
1143          closed and the application thus needs to be told, even if it
1144          is likely that the same socket(s) will again be used further
1145          down.  If the name has not yet been resolved, it is likely
1146          that new sockets have been opened in an attempt to contact
1147          another resolver. */
1148       singlesocket(multi, easy);
1149
1150       if(dns) {
1151         /* Perform the next step in the connection phase, and then move on
1152            to the WAITCONNECT state */
1153         easy->result = Curl_async_resolved(easy->easy_conn,
1154                                            &protocol_connect);
1155
1156         if(CURLE_OK != easy->result)
1157           /* if Curl_async_resolved() returns failure, the connection struct
1158              is already freed and gone */
1159           easy->easy_conn = NULL;           /* no more connection */
1160         else {
1161           /* call again please so that we get the next socket setup */
1162           result = CURLM_CALL_MULTI_PERFORM;
1163           if(protocol_connect)
1164             multistate(easy, multi->pipelining_enabled?
1165                        CURLM_STATE_WAITDO:CURLM_STATE_DO);
1166           else {
1167 #ifndef CURL_DISABLE_HTTP
1168             if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1169               multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1170             else
1171 #endif
1172               multistate(easy, CURLM_STATE_WAITCONNECT);
1173           }
1174         }
1175       }
1176
1177       if(CURLE_OK != easy->result) {
1178         /* failure detected */
1179         disconnect_conn = TRUE;
1180         break;
1181       }
1182     }
1183     break;
1184
1185 #ifndef CURL_DISABLE_HTTP
1186     case CURLM_STATE_WAITPROXYCONNECT:
1187       /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
1188       easy->result = Curl_http_connect(easy->easy_conn, &protocol_connect);
1189
1190       if(easy->easy_conn->bits.proxy_connect_closed) {
1191         /* reset the error buffer */
1192         if(data->set.errorbuffer)
1193           data->set.errorbuffer[0] = '\0';
1194         data->state.errorbuf = FALSE;
1195
1196         easy->result = CURLE_OK;
1197         result = CURLM_CALL_MULTI_PERFORM;
1198         multistate(easy, CURLM_STATE_CONNECT);
1199       }
1200       else if(CURLE_OK == easy->result) {
1201         if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
1202           multistate(easy, CURLM_STATE_WAITCONNECT);
1203       }
1204       break;
1205 #endif
1206
1207     case CURLM_STATE_WAITCONNECT:
1208       /* awaiting a completion of an asynch connect */
1209       easy->result = Curl_is_connected(easy->easy_conn,
1210                                        FIRSTSOCKET,
1211                                        &connected);
1212       if(connected) {
1213
1214         if(!easy->result)
1215           /* if everything is still fine we do the protocol-specific connect
1216              setup */
1217           easy->result = Curl_protocol_connect(easy->easy_conn,
1218                                                &protocol_connect);
1219       }
1220
1221       if(CURLE_OK != easy->result) {
1222         /* failure detected */
1223         /* Just break, the cleaning up is handled all in one place */
1224         disconnect_conn = TRUE;
1225         break;
1226       }
1227
1228       if(connected) {
1229         if(!protocol_connect) {
1230           /* We have a TCP connection, but 'protocol_connect' may be false
1231              and then we continue to 'STATE_PROTOCONNECT'. If protocol
1232              connect is TRUE, we move on to STATE_DO.
1233              BUT if we are using a proxy we must change to WAITPROXYCONNECT
1234           */
1235 #ifndef CURL_DISABLE_HTTP
1236           if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1237             multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1238           else
1239 #endif
1240             multistate(easy, CURLM_STATE_PROTOCONNECT);
1241
1242         }
1243         else
1244           /* after the connect has completed, go WAITDO or DO */
1245           multistate(easy, multi->pipelining_enabled?
1246                      CURLM_STATE_WAITDO:CURLM_STATE_DO);
1247
1248         result = CURLM_CALL_MULTI_PERFORM;
1249       }
1250       break;
1251
1252     case CURLM_STATE_PROTOCONNECT:
1253       /* protocol-specific connect phase */
1254       easy->result = Curl_protocol_connecting(easy->easy_conn,
1255                                               &protocol_connect);
1256       if((easy->result == CURLE_OK) && protocol_connect) {
1257         /* after the connect has completed, go WAITDO or DO */
1258         multistate(easy, multi->pipelining_enabled?
1259                    CURLM_STATE_WAITDO:CURLM_STATE_DO);
1260         result = CURLM_CALL_MULTI_PERFORM;
1261       }
1262       else if(easy->result) {
1263         /* failure detected */
1264         Curl_posttransfer(data);
1265         Curl_done(&easy->easy_conn, easy->result, TRUE);
1266         disconnect_conn = TRUE;
1267       }
1268       break;
1269
1270     case CURLM_STATE_WAITDO:
1271       /* Wait for our turn to DO when we're pipelining requests */
1272 #ifdef DEBUGBUILD
1273       infof(data, "WAITDO: Conn %ld send pipe %zu inuse %d athead %d\n",
1274             easy->easy_conn->connection_id,
1275             easy->easy_conn->send_pipe->size,
1276             easy->easy_conn->writechannel_inuse?1:0,
1277             isHandleAtHead(data,
1278                            easy->easy_conn->send_pipe)?1:0);
1279 #endif
1280       if(!easy->easy_conn->writechannel_inuse &&
1281          isHandleAtHead(data,
1282                         easy->easy_conn->send_pipe)) {
1283         /* Grab the channel */
1284         easy->easy_conn->writechannel_inuse = TRUE;
1285         multistate(easy, CURLM_STATE_DO);
1286         result = CURLM_CALL_MULTI_PERFORM;
1287       }
1288       break;
1289
1290     case CURLM_STATE_DO:
1291       if(data->set.connect_only) {
1292         /* keep connection open for application to use the socket */
1293         easy->easy_conn->bits.close = FALSE;
1294         multistate(easy, CURLM_STATE_DONE);
1295         easy->result = CURLE_OK;
1296         result = CURLM_CALL_MULTI_PERFORM;
1297       }
1298       else {
1299         /* Perform the protocol's DO action */
1300         easy->result = Curl_do(&easy->easy_conn,
1301                                &dophase_done);
1302
1303         if(CURLE_OK == easy->result) {
1304           if(!dophase_done) {
1305             /* some steps needed for wildcard matching */
1306             if(data->set.wildcardmatch) {
1307               struct WildcardData *wc = &data->wildcard;
1308               if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
1309                 /* skip some states if it is important */
1310                 Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
1311                 multistate(easy, CURLM_STATE_DONE);
1312                 result = CURLM_CALL_MULTI_PERFORM;
1313                 break;
1314               }
1315             }
1316             /* DO was not completed in one function call, we must continue
1317                DOING... */
1318             multistate(easy, CURLM_STATE_DOING);
1319             result = CURLM_OK;
1320           }
1321
1322           /* after DO, go DO_DONE... or DO_MORE */
1323           else if(easy->easy_conn->bits.do_more) {
1324             /* we're supposed to do more, but we need to sit down, relax
1325                and wait a little while first */
1326             multistate(easy, CURLM_STATE_DO_MORE);
1327             result = CURLM_OK;
1328           }
1329           else {
1330             /* we're done with the DO, now DO_DONE */
1331             multistate(easy, CURLM_STATE_DO_DONE);
1332             result = CURLM_CALL_MULTI_PERFORM;
1333           }
1334         }
1335         else if((CURLE_SEND_ERROR == easy->result) &&
1336                 easy->easy_conn->bits.reuse) {
1337           /*
1338            * In this situation, a connection that we were trying to use
1339            * may have unexpectedly died.  If possible, send the connection
1340            * back to the CONNECT phase so we can try again.
1341            */
1342           char *newurl = NULL;
1343           followtype follow=FOLLOW_NONE;
1344           CURLcode drc;
1345           bool retry = FALSE;
1346
1347           drc = Curl_retry_request(easy->easy_conn, &newurl);
1348           if(drc) {
1349             /* a failure here pretty much implies an out of memory */
1350             easy->result = drc;
1351             disconnect_conn = TRUE;
1352           }
1353           else
1354             retry = (newurl)?TRUE:FALSE;
1355
1356           Curl_posttransfer(data);
1357           drc = Curl_done(&easy->easy_conn, easy->result, FALSE);
1358
1359           /* When set to retry the connection, we must to go back to
1360            * the CONNECT state */
1361           if(retry) {
1362             if((drc == CURLE_OK) || (drc == CURLE_SEND_ERROR)) {
1363               follow = FOLLOW_RETRY;
1364               drc = Curl_follow(data, newurl, follow);
1365               if(drc == CURLE_OK) {
1366                 multistate(easy, CURLM_STATE_CONNECT);
1367                 result = CURLM_CALL_MULTI_PERFORM;
1368                 easy->result = CURLE_OK;
1369               }
1370               else {
1371                 /* Follow failed */
1372                 easy->result = drc;
1373                 free(newurl);
1374               }
1375             }
1376             else {
1377               /* done didn't return OK or SEND_ERROR */
1378               easy->result = drc;
1379               free(newurl);
1380             }
1381           }
1382           else {
1383             /* Have error handler disconnect conn if we can't retry */
1384             disconnect_conn = TRUE;
1385           }
1386         }
1387         else {
1388           /* failure detected */
1389           Curl_posttransfer(data);
1390           Curl_done(&easy->easy_conn, easy->result, FALSE);
1391           disconnect_conn = TRUE;
1392         }
1393       }
1394       break;
1395
1396     case CURLM_STATE_DOING:
1397       /* we continue DOING until the DO phase is complete */
1398       easy->result = Curl_protocol_doing(easy->easy_conn,
1399                                          &dophase_done);
1400       if(CURLE_OK == easy->result) {
1401         if(dophase_done) {
1402           /* after DO, go DO_DONE or DO_MORE */
1403           multistate(easy, easy->easy_conn->bits.do_more?
1404                      CURLM_STATE_DO_MORE:
1405                      CURLM_STATE_DO_DONE);
1406           result = CURLM_CALL_MULTI_PERFORM;
1407         } /* dophase_done */
1408       }
1409       else {
1410         /* failure detected */
1411         Curl_posttransfer(data);
1412         Curl_done(&easy->easy_conn, easy->result, FALSE);
1413         disconnect_conn = TRUE;
1414       }
1415       break;
1416
1417     case CURLM_STATE_DO_MORE:
1418       /*
1419        * When we are connected, DO MORE and then go DO_DONE
1420        */
1421       easy->result = Curl_do_more(easy->easy_conn, &dophase_done);
1422
1423       /* No need to remove this handle from the send pipeline here since that
1424          is done in Curl_done() */
1425       if(CURLE_OK == easy->result) {
1426         if(dophase_done) {
1427           multistate(easy, CURLM_STATE_DO_DONE);
1428           result = CURLM_CALL_MULTI_PERFORM;
1429         }
1430         else
1431           /* stay in DO_MORE */
1432           result = CURLM_OK;
1433       }
1434       else {
1435         /* failure detected */
1436         Curl_posttransfer(data);
1437         Curl_done(&easy->easy_conn, easy->result, FALSE);
1438         disconnect_conn = TRUE;
1439       }
1440       break;
1441
1442     case CURLM_STATE_DO_DONE:
1443       /* Move ourselves from the send to recv pipeline */
1444       moveHandleFromSendToRecvPipeline(data, easy->easy_conn);
1445       /* Check if we can move pending requests to send pipe */
1446       checkPendPipeline(easy->easy_conn);
1447       multistate(easy, CURLM_STATE_WAITPERFORM);
1448       result = CURLM_CALL_MULTI_PERFORM;
1449       break;
1450
1451     case CURLM_STATE_WAITPERFORM:
1452       /* Wait for our turn to PERFORM */
1453       if(!easy->easy_conn->readchannel_inuse &&
1454          isHandleAtHead(data,
1455                         easy->easy_conn->recv_pipe)) {
1456         /* Grab the channel */
1457         easy->easy_conn->readchannel_inuse = TRUE;
1458         multistate(easy, CURLM_STATE_PERFORM);
1459         result = CURLM_CALL_MULTI_PERFORM;
1460       }
1461 #ifdef DEBUGBUILD
1462       else {
1463         infof(data, "WAITPERFORM: Conn %ld recv pipe %zu inuse %d athead %d\n",
1464               easy->easy_conn->connection_id,
1465               easy->easy_conn->recv_pipe->size,
1466               easy->easy_conn->readchannel_inuse?1:0,
1467               isHandleAtHead(data,
1468                              easy->easy_conn->recv_pipe)?1:0);
1469       }
1470 #endif
1471       break;
1472
1473     case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1474       /* if both rates are within spec, resume transfer */
1475       if(Curl_pgrsUpdate(easy->easy_conn))
1476         easy->result = CURLE_ABORTED_BY_CALLBACK;
1477       else
1478         easy->result = Curl_speedcheck(data, now);
1479
1480       if(( (data->set.max_send_speed == 0) ||
1481            (data->progress.ulspeed < data->set.max_send_speed ))  &&
1482          ( (data->set.max_recv_speed == 0) ||
1483            (data->progress.dlspeed < data->set.max_recv_speed)))
1484         multistate(easy, CURLM_STATE_PERFORM);
1485       break;
1486
1487     case CURLM_STATE_PERFORM:
1488       {
1489       char *newurl = NULL;
1490       bool retry = FALSE;
1491
1492       /* check if over send speed */
1493       if((data->set.max_send_speed > 0) &&
1494          (data->progress.ulspeed > data->set.max_send_speed)) {
1495         int buffersize;
1496
1497         multistate(easy, CURLM_STATE_TOOFAST);
1498
1499         /* calculate upload rate-limitation timeout. */
1500         buffersize = (int)(data->set.buffer_size ?
1501                            data->set.buffer_size : BUFSIZE);
1502         timeout_ms = Curl_sleep_time(data->set.max_send_speed,
1503                                      data->progress.ulspeed, buffersize);
1504         Curl_expire(data, timeout_ms);
1505         break;
1506       }
1507
1508       /* check if over recv speed */
1509       if((data->set.max_recv_speed > 0) &&
1510          (data->progress.dlspeed > data->set.max_recv_speed)) {
1511         int buffersize;
1512
1513         multistate(easy, CURLM_STATE_TOOFAST);
1514
1515          /* Calculate download rate-limitation timeout. */
1516         buffersize = (int)(data->set.buffer_size ?
1517                            data->set.buffer_size : BUFSIZE);
1518         timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
1519                                      data->progress.dlspeed, buffersize);
1520         Curl_expire(data, timeout_ms);
1521         break;
1522       }
1523
1524       /* read/write data if it is ready to do so */
1525       easy->result = Curl_readwrite(easy->easy_conn, &done);
1526
1527       k = &data->req;
1528
1529       if(!(k->keepon & KEEP_RECV)) {
1530         /* We're done receiving */
1531         easy->easy_conn->readchannel_inuse = FALSE;
1532       }
1533
1534       if(!(k->keepon & KEEP_SEND)) {
1535         /* We're done sending */
1536         easy->easy_conn->writechannel_inuse = FALSE;
1537       }
1538
1539       if(done || (easy->result == CURLE_RECV_ERROR)) {
1540         /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
1541          * condition and the server closed the re-used connection exactly when
1542          * we wanted to use it, so figure out if that is indeed the case.
1543          */
1544         CURLcode ret = Curl_retry_request(easy->easy_conn, &newurl);
1545         if(!ret)
1546           retry = (newurl)?TRUE:FALSE;
1547
1548         if(retry)
1549           /* if we are to retry, set the result to OK */
1550           easy->result = CURLE_OK;
1551       }
1552
1553       if(easy->result) {
1554         /*
1555          * The transfer phase returned error, we mark the connection to get
1556          * closed to prevent being re-used. This is because we can't possibly
1557          * know if the connection is in a good shape or not now.  Unless it is
1558          * a protocol which uses two "channels" like FTP, as then the error
1559          * happened in the data connection.
1560          */
1561
1562         if(!(easy->easy_conn->handler->flags & PROTOPT_DUAL))
1563           easy->easy_conn->bits.close = TRUE;
1564
1565         Curl_posttransfer(data);
1566         Curl_done(&easy->easy_conn, easy->result, FALSE);
1567       }
1568       else if(done) {
1569         followtype follow=FOLLOW_NONE;
1570
1571         /* call this even if the readwrite function returned error */
1572         Curl_posttransfer(data);
1573
1574         /* we're no longer receiving */
1575         moveHandleFromRecvToDonePipeline(data,
1576                                          easy->easy_conn);
1577
1578         /* expire the new receiving pipeline head */
1579         if(easy->easy_conn->recv_pipe->head)
1580           Curl_expire(easy->easy_conn->recv_pipe->head->ptr, 1);
1581
1582         /* Check if we can move pending requests to send pipe */
1583         checkPendPipeline(easy->easy_conn);
1584
1585         /* When we follow redirects or is set to retry the connection, we must
1586            to go back to the CONNECT state */
1587         if(data->req.newurl || retry) {
1588           if(!retry) {
1589             /* if the URL is a follow-location and not just a retried request
1590                then figure out the URL here */
1591             newurl = data->req.newurl;
1592             data->req.newurl = NULL;
1593             follow = FOLLOW_REDIR;
1594           }
1595           else
1596             follow = FOLLOW_RETRY;
1597           easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
1598           if(easy->result == CURLE_OK)
1599             easy->result = Curl_follow(data, newurl, follow);
1600           if(CURLE_OK == easy->result) {
1601             multistate(easy, CURLM_STATE_CONNECT);
1602             result = CURLM_CALL_MULTI_PERFORM;
1603             newurl = NULL; /* handed over the memory ownership to
1604                               Curl_follow(), make sure we don't free() it
1605                               here */
1606           }
1607         }
1608         else {
1609           /* after the transfer is done, go DONE */
1610
1611           /* but first check to see if we got a location info even though we're
1612              not following redirects */
1613           if(data->req.location) {
1614             if(newurl)
1615               free(newurl);
1616             newurl = data->req.location;
1617             data->req.location = NULL;
1618             easy->result = Curl_follow(data, newurl, FOLLOW_FAKE);
1619             if(CURLE_OK == easy->result)
1620               newurl = NULL; /* allocation was handed over Curl_follow() */
1621             else
1622               disconnect_conn = TRUE;
1623           }
1624
1625           multistate(easy, CURLM_STATE_DONE);
1626           result = CURLM_CALL_MULTI_PERFORM;
1627         }
1628       }
1629
1630       if(newurl)
1631         free(newurl);
1632       break;
1633       }
1634
1635     case CURLM_STATE_DONE:
1636
1637       if(easy->easy_conn) {
1638         /* Remove ourselves from the receive and done pipelines. Handle
1639            should be on one of these lists, depending upon how we got here. */
1640         Curl_removeHandleFromPipeline(data,
1641                                       easy->easy_conn->recv_pipe);
1642         Curl_removeHandleFromPipeline(data,
1643                                       easy->easy_conn->done_pipe);
1644         /* Check if we can move pending requests to send pipe */
1645         checkPendPipeline(easy->easy_conn);
1646
1647         if(easy->easy_conn->bits.stream_was_rewound) {
1648           /* This request read past its response boundary so we quickly let
1649              the other requests consume those bytes since there is no
1650              guarantee that the socket will become active again */
1651           result = CURLM_CALL_MULTI_PERFORM;
1652         }
1653
1654         /* post-transfer command */
1655         easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
1656         /*
1657          * If there are other handles on the pipeline, Curl_done won't set
1658          * easy_conn to NULL.  In such a case, curl_multi_remove_handle() can
1659          * access free'd data, if the connection is free'd and the handle
1660          * removed before we perform the processing in CURLM_STATE_COMPLETED
1661          */
1662         if(easy->easy_conn)
1663           easy->easy_conn = NULL;
1664       }
1665
1666       if(data->set.wildcardmatch) {
1667         if(data->wildcard.state != CURLWC_DONE) {
1668           /* if a wildcard is set and we are not ending -> lets start again
1669              with CURLM_STATE_INIT */
1670           result = CURLM_CALL_MULTI_PERFORM;
1671           multistate(easy, CURLM_STATE_INIT);
1672           break;
1673         }
1674       }
1675
1676       /* after we have DONE what we're supposed to do, go COMPLETED, and
1677          it doesn't matter what the Curl_done() returned! */
1678       multistate(easy, CURLM_STATE_COMPLETED);
1679
1680       break;
1681
1682     case CURLM_STATE_COMPLETED:
1683       /* this is a completed transfer, it is likely to still be connected */
1684
1685       /* This node should be delinked from the list now and we should post
1686          an information message that we are complete. */
1687
1688       /* Important: reset the conn pointer so that we don't point to memory
1689          that could be freed anytime */
1690       easy->easy_conn = NULL;
1691
1692       Curl_expire(data, 0); /* stop all timers */
1693       break;
1694
1695     case CURLM_STATE_MSGSENT:
1696       return CURLM_OK; /* do nothing */
1697
1698     default:
1699       return CURLM_INTERNAL_ERROR;
1700     }
1701
1702     if(easy->state < CURLM_STATE_COMPLETED) {
1703       if(CURLE_OK != easy->result) {
1704         /*
1705          * If an error was returned, and we aren't in completed state now,
1706          * then we go to completed and consider this transfer aborted.
1707          */
1708
1709         /* NOTE: no attempt to disconnect connections must be made
1710            in the case blocks above - cleanup happens only here */
1711
1712         data->state.pipe_broke = FALSE;
1713
1714         if(easy->easy_conn) {
1715           /* if this has a connection, unsubscribe from the pipelines */
1716           easy->easy_conn->writechannel_inuse = FALSE;
1717           easy->easy_conn->readchannel_inuse = FALSE;
1718           Curl_removeHandleFromPipeline(data,
1719                                         easy->easy_conn->send_pipe);
1720           Curl_removeHandleFromPipeline(data,
1721                                         easy->easy_conn->recv_pipe);
1722           Curl_removeHandleFromPipeline(data,
1723                                         easy->easy_conn->done_pipe);
1724           /* Check if we can move pending requests to send pipe */
1725           checkPendPipeline(easy->easy_conn);
1726
1727           if(disconnect_conn) {
1728             /* disconnect properly */
1729             Curl_disconnect(easy->easy_conn, /* dead_connection */ FALSE);
1730
1731             /* This is where we make sure that the easy_conn pointer is reset.
1732                We don't have to do this in every case block above where a
1733                failure is detected */
1734             easy->easy_conn = NULL;
1735           }
1736         }
1737         else if(easy->state == CURLM_STATE_CONNECT) {
1738           /* Curl_connect() failed */
1739           (void)Curl_posttransfer(data);
1740         }
1741
1742         multistate(easy, CURLM_STATE_COMPLETED);
1743       }
1744       /* if there's still a connection to use, call the progress function */
1745       else if(easy->easy_conn && Curl_pgrsUpdate(easy->easy_conn)) {
1746         /* aborted due to progress callback return code must close the
1747            connection */
1748         easy->easy_conn->bits.close = TRUE;
1749
1750         /* if not yet in DONE state, go there, otherwise COMPLETED */
1751         multistate(easy, (easy->state < CURLM_STATE_DONE)?
1752                    CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
1753         result = CURLM_CALL_MULTI_PERFORM;
1754       }
1755     }
1756   } WHILE_FALSE; /* just to break out from! */
1757
1758   if(CURLM_STATE_COMPLETED == easy->state) {
1759     /* now fill in the Curl_message with this info */
1760     msg = &easy->msg;
1761
1762     msg->extmsg.msg = CURLMSG_DONE;
1763     msg->extmsg.easy_handle = data;
1764     msg->extmsg.data.result = easy->result;
1765
1766     result = multi_addmsg(multi, msg);
1767
1768     multistate(easy, CURLM_STATE_MSGSENT);
1769   }
1770
1771   return result;
1772 }
1773
1774
1775 CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
1776 {
1777   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
1778   struct Curl_one_easy *easy;
1779   CURLMcode returncode=CURLM_OK;
1780   struct Curl_tree *t;
1781   struct timeval now = Curl_tvnow();
1782
1783   if(!GOOD_MULTI_HANDLE(multi))
1784     return CURLM_BAD_HANDLE;
1785
1786   easy=multi->easy.next;
1787   while(easy != &multi->easy) {
1788     CURLMcode result;
1789     struct WildcardData *wc = &easy->easy_handle->wildcard;
1790
1791     if(easy->easy_handle->set.wildcardmatch) {
1792       if(!wc->filelist) {
1793         CURLcode ret = Curl_wildcard_init(wc); /* init wildcard structures */
1794         if(ret)
1795           return CURLM_OUT_OF_MEMORY;
1796       }
1797     }
1798
1799     do
1800       result = multi_runsingle(multi, now, easy);
1801     while(CURLM_CALL_MULTI_PERFORM == result);
1802
1803     if(easy->easy_handle->set.wildcardmatch) {
1804       /* destruct wildcard structures if it is needed */
1805       if(wc->state == CURLWC_DONE || result)
1806         Curl_wildcard_dtor(wc);
1807     }
1808
1809     if(result)
1810       returncode = result;
1811
1812     easy = easy->next; /* operate on next handle */
1813   }
1814
1815   /*
1816    * Simply remove all expired timers from the splay since handles are dealt
1817    * with unconditionally by this function and curl_multi_timeout() requires
1818    * that already passed/handled expire times are removed from the splay.
1819    *
1820    * It is important that the 'now' value is set at the entry of this function
1821    * and not for the current time as it may have ticked a little while since
1822    * then and then we risk this loop to remove timers that actually have not
1823    * been handled!
1824    */
1825   do {
1826     multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
1827     if(t)
1828       /* the removed may have another timeout in queue */
1829       (void)add_next_timeout(now, multi, t->payload);
1830
1831   } while(t);
1832
1833   *running_handles = multi->num_alive;
1834
1835   if(CURLM_OK >= returncode)
1836     update_timer(multi);
1837
1838   return returncode;
1839 }
1840
1841 static void close_all_connections(struct Curl_multi *multi)
1842 {
1843   struct connectdata *conn;
1844
1845   conn = Curl_conncache_find_first_connection(multi->conn_cache);
1846   while(conn) {
1847     conn->data = multi->closure_handle;
1848
1849     /* This will remove the connection from the cache */
1850     (void)Curl_disconnect(conn, FALSE);
1851
1852     conn = Curl_conncache_find_first_connection(multi->conn_cache);
1853   }
1854 }
1855
1856 CURLMcode curl_multi_cleanup(CURLM *multi_handle)
1857 {
1858   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
1859   struct Curl_one_easy *easy;
1860   struct Curl_one_easy *nexteasy;
1861
1862   if(GOOD_MULTI_HANDLE(multi)) {
1863     multi->type = 0; /* not good anymore */
1864
1865     /* Close all the connections in the connection cache */
1866     close_all_connections(multi);
1867
1868     Curl_close(multi->closure_handle);
1869     multi->closure_handle = NULL;
1870
1871     Curl_hash_destroy(multi->sockhash);
1872     multi->sockhash = NULL;
1873
1874     Curl_conncache_destroy(multi->conn_cache);
1875     multi->conn_cache = NULL;
1876
1877     /* remove the pending list of messages */
1878     Curl_llist_destroy(multi->msglist, NULL);
1879     multi->msglist = NULL;
1880
1881     /* remove all easy handles */
1882     easy = multi->easy.next;
1883     while(easy != &multi->easy) {
1884       nexteasy=easy->next;
1885       if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
1886         /* clear out the usage of the shared DNS cache */
1887         Curl_hostcache_clean(easy->easy_handle);
1888         easy->easy_handle->dns.hostcache = NULL;
1889         easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
1890       }
1891
1892       /* Clear the pointer to the connection cache */
1893       easy->easy_handle->state.conn_cache = NULL;
1894
1895       Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association */
1896
1897       free(easy);
1898       easy = nexteasy;
1899     }
1900
1901     Curl_hash_destroy(multi->hostcache);
1902     multi->hostcache = NULL;
1903
1904     free(multi);
1905
1906     return CURLM_OK;
1907   }
1908   else
1909     return CURLM_BAD_HANDLE;
1910 }
1911
1912 /*
1913  * curl_multi_info_read()
1914  *
1915  * This function is the primary way for a multi/multi_socket application to
1916  * figure out if a transfer has ended. We MUST make this function as fast as
1917  * possible as it will be polled frequently and we MUST NOT scan any lists in
1918  * here to figure out things. We must scale fine to thousands of handles and
1919  * beyond. The current design is fully O(1).
1920  */
1921
1922 CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
1923 {
1924   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
1925   struct Curl_message *msg;
1926
1927   *msgs_in_queue = 0; /* default to none */
1928
1929   if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
1930     /* there is one or more messages in the list */
1931     struct curl_llist_element *e;
1932
1933     /* extract the head of the list to return */
1934     e = multi->msglist->head;
1935
1936     msg = e->ptr;
1937
1938     /* remove the extracted entry */
1939     Curl_llist_remove(multi->msglist, e, NULL);
1940
1941     *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
1942
1943     return &msg->extmsg;
1944   }
1945   else
1946     return NULL;
1947 }
1948
1949 /*
1950  * singlesocket() checks what sockets we deal with and their "action state"
1951  * and if we have a different state in any of those sockets from last time we
1952  * call the callback accordingly.
1953  */
1954 static void singlesocket(struct Curl_multi *multi,
1955                          struct Curl_one_easy *easy)
1956 {
1957   curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
1958   int i;
1959   struct Curl_sh_entry *entry;
1960   curl_socket_t s;
1961   int num;
1962   unsigned int curraction;
1963   struct Curl_one_easy *easy_by_hash;
1964   bool remove_sock_from_hash;
1965
1966   for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
1967     socks[i] = CURL_SOCKET_BAD;
1968
1969   /* Fill in the 'current' struct with the state as it is now: what sockets to
1970      supervise and for what actions */
1971   curraction = multi_getsock(easy, socks, MAX_SOCKSPEREASYHANDLE);
1972
1973   /* We have 0 .. N sockets already and we get to know about the 0 .. M
1974      sockets we should have from now on. Detect the differences, remove no
1975      longer supervised ones and add new ones */
1976
1977   /* walk over the sockets we got right now */
1978   for(i=0; (i< MAX_SOCKSPEREASYHANDLE) &&
1979         (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
1980       i++) {
1981     int action = CURL_POLL_NONE;
1982
1983     s = socks[i];
1984
1985     /* get it from the hash */
1986     entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
1987
1988     if(curraction & GETSOCK_READSOCK(i))
1989       action |= CURL_POLL_IN;
1990     if(curraction & GETSOCK_WRITESOCK(i))
1991       action |= CURL_POLL_OUT;
1992
1993     if(entry) {
1994       /* yeps, already present so check if it has the same action set */
1995       if(entry->action == action)
1996         /* same, continue */
1997         continue;
1998     }
1999     else {
2000       /* this is a socket we didn't have before, add it! */
2001       entry = sh_addentry(multi->sockhash, s, easy->easy_handle);
2002       if(!entry)
2003         /* fatal */
2004         return;
2005     }
2006
2007     /* we know (entry != NULL) at this point, see the logic above */
2008     if(multi->socket_cb)
2009       multi->socket_cb(easy->easy_handle,
2010                        s,
2011                        action,
2012                        multi->socket_userp,
2013                        entry->socketp);
2014
2015     entry->action = action; /* store the current action state */
2016   }
2017
2018   num = i; /* number of sockets */
2019
2020   /* when we've walked over all the sockets we should have right now, we must
2021      make sure to detect sockets that are removed */
2022   for(i=0; i< easy->numsocks; i++) {
2023     int j;
2024     s = easy->sockets[i];
2025     for(j=0; j<num; j++) {
2026       if(s == socks[j]) {
2027         /* this is still supervised */
2028         s = CURL_SOCKET_BAD;
2029         break;
2030       }
2031     }
2032     if(s != CURL_SOCKET_BAD) {
2033
2034       /* this socket has been removed. Tell the app to remove it */
2035       remove_sock_from_hash = TRUE;
2036
2037       entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
2038       if(entry) {
2039         /* check if the socket to be removed serves a connection which has
2040            other easy-s in a pipeline. In this case the socket should not be
2041            removed. */
2042         struct connectdata *easy_conn;
2043
2044         easy_by_hash = entry->easy->multi_pos;
2045         easy_conn = easy_by_hash->easy_conn;
2046         if(easy_conn) {
2047           if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
2048             /* the handle should not be removed from the pipe yet */
2049             remove_sock_from_hash = FALSE;
2050
2051             /* Update the sockhash entry to instead point to the next in line
2052                for the recv_pipe, or the first (in case this particular easy
2053                isn't already) */
2054             if(entry->easy == easy->easy_handle) {
2055               if(isHandleAtHead(easy->easy_handle, easy_conn->recv_pipe))
2056                 entry->easy = easy_conn->recv_pipe->head->next->ptr;
2057               else
2058                 entry->easy = easy_conn->recv_pipe->head->ptr;
2059             }
2060           }
2061           if(easy_conn->send_pipe  && easy_conn->send_pipe->size > 1) {
2062             /* the handle should not be removed from the pipe yet */
2063             remove_sock_from_hash = FALSE;
2064
2065             /* Update the sockhash entry to instead point to the next in line
2066                for the send_pipe, or the first (in case this particular easy
2067                isn't already) */
2068             if(entry->easy == easy->easy_handle) {
2069               if(isHandleAtHead(easy->easy_handle, easy_conn->send_pipe))
2070                 entry->easy = easy_conn->send_pipe->head->next->ptr;
2071               else
2072                 entry->easy = easy_conn->send_pipe->head->ptr;
2073             }
2074           }
2075           /* Don't worry about overwriting recv_pipe head with send_pipe_head,
2076              when action will be asked on the socket (see multi_socket()), the
2077              head of the correct pipe will be taken according to the
2078              action. */
2079         }
2080       }
2081       else
2082         /* just a precaution, this socket really SHOULD be in the hash already
2083            but in case it isn't, we don't have to tell the app to remove it
2084            either since it never got to know about it */
2085         remove_sock_from_hash = FALSE;
2086
2087       if(remove_sock_from_hash) {
2088         /* in this case 'entry' is always non-NULL */
2089         if(multi->socket_cb)
2090           multi->socket_cb(easy->easy_handle,
2091                            s,
2092                            CURL_POLL_REMOVE,
2093                            multi->socket_userp,
2094                            entry->socketp);
2095         sh_delentry(multi->sockhash, s);
2096       }
2097
2098     }
2099   }
2100
2101   memcpy(easy->sockets, socks, num*sizeof(curl_socket_t));
2102   easy->numsocks = num;
2103 }
2104
2105 /*
2106  * add_next_timeout()
2107  *
2108  * Each SessionHandle has a list of timeouts. The add_next_timeout() is called
2109  * when it has just been removed from the splay tree because the timeout has
2110  * expired. This function is then to advance in the list to pick the next
2111  * timeout to use (skip the already expired ones) and add this node back to
2112  * the splay tree again.
2113  *
2114  * The splay tree only has each sessionhandle as a single node and the nearest
2115  * timeout is used to sort it on.
2116  */
2117 static CURLMcode add_next_timeout(struct timeval now,
2118                                   struct Curl_multi *multi,
2119                                   struct SessionHandle *d)
2120 {
2121   struct timeval *tv = &d->state.expiretime;
2122   struct curl_llist *list = d->state.timeoutlist;
2123   struct curl_llist_element *e;
2124
2125   /* move over the timeout list for this specific handle and remove all
2126      timeouts that are now passed tense and store the next pending
2127      timeout in *tv */
2128   for(e = list->head; e; ) {
2129     struct curl_llist_element *n = e->next;
2130     long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
2131     if(diff <= 0)
2132       /* remove outdated entry */
2133       Curl_llist_remove(list, e, NULL);
2134     else
2135       /* the list is sorted so get out on the first mismatch */
2136       break;
2137     e = n;
2138   }
2139   e = list->head;
2140   if(!e) {
2141     /* clear the expire times within the handles that we remove from the
2142        splay tree */
2143     tv->tv_sec = 0;
2144     tv->tv_usec = 0;
2145   }
2146   else {
2147     /* copy the first entry to 'tv' */
2148     memcpy(tv, e->ptr, sizeof(*tv));
2149
2150     /* remove first entry from list */
2151     Curl_llist_remove(list, e, NULL);
2152
2153     /* insert this node again into the splay */
2154     multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2155                                        &d->state.timenode);
2156   }
2157   return CURLM_OK;
2158 }
2159
2160
2161 static CURLMcode multi_socket(struct Curl_multi *multi,
2162                               bool checkall,
2163                               curl_socket_t s,
2164                               int ev_bitmask,
2165                               int *running_handles)
2166 {
2167   CURLMcode result = CURLM_OK;
2168   struct SessionHandle *data = NULL;
2169   struct Curl_tree *t;
2170   struct timeval now = Curl_tvnow();
2171
2172   if(checkall) {
2173     struct Curl_one_easy *easyp;
2174     /* *perform() deals with running_handles on its own */
2175     result = curl_multi_perform(multi, running_handles);
2176
2177     /* walk through each easy handle and do the socket state change magic
2178        and callbacks */
2179     easyp=multi->easy.next;
2180     while(easyp != &multi->easy) {
2181       singlesocket(multi, easyp);
2182       easyp = easyp->next;
2183     }
2184
2185     /* or should we fall-through and do the timer-based stuff? */
2186     return result;
2187   }
2188   else if(s != CURL_SOCKET_TIMEOUT) {
2189
2190     struct Curl_sh_entry *entry =
2191       Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
2192
2193     if(!entry)
2194       /* Unmatched socket, we can't act on it but we ignore this fact.  In
2195          real-world tests it has been proved that libevent can in fact give
2196          the application actions even though the socket was just previously
2197          asked to get removed, so thus we better survive stray socket actions
2198          and just move on. */
2199       ;
2200     else {
2201       data = entry->easy;
2202
2203       if(data->magic != CURLEASY_MAGIC_NUMBER)
2204         /* bad bad bad bad bad bad bad */
2205         return CURLM_INTERNAL_ERROR;
2206
2207       /* If the pipeline is enabled, take the handle which is in the head of
2208          the pipeline. If we should write into the socket, take the send_pipe
2209          head.  If we should read from the socket, take the recv_pipe head. */
2210       if(data->set.one_easy->easy_conn) {
2211         if((ev_bitmask & CURL_POLL_OUT) &&
2212            data->set.one_easy->easy_conn->send_pipe &&
2213            data->set.one_easy->easy_conn->send_pipe->head)
2214           data = data->set.one_easy->easy_conn->send_pipe->head->ptr;
2215         else if((ev_bitmask & CURL_POLL_IN) &&
2216                 data->set.one_easy->easy_conn->recv_pipe &&
2217                 data->set.one_easy->easy_conn->recv_pipe->head)
2218           data = data->set.one_easy->easy_conn->recv_pipe->head->ptr;
2219       }
2220
2221       if(data->set.one_easy->easy_conn &&
2222          !(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2223         /* set socket event bitmask if they're not locked */
2224         data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
2225
2226       do
2227         result = multi_runsingle(multi, now, data->set.one_easy);
2228       while(CURLM_CALL_MULTI_PERFORM == result);
2229
2230       if(data->set.one_easy->easy_conn &&
2231          !(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2232         /* clear the bitmask only if not locked */
2233         data->set.one_easy->easy_conn->cselect_bits = 0;
2234
2235       if(CURLM_OK >= result)
2236         /* get the socket(s) and check if the state has been changed since
2237            last */
2238         singlesocket(multi, data->set.one_easy);
2239
2240       /* Now we fall-through and do the timer-based stuff, since we don't want
2241          to force the user to have to deal with timeouts as long as at least
2242          one connection in fact has traffic. */
2243
2244       data = NULL; /* set data to NULL again to avoid calling
2245                       multi_runsingle() in case there's no need to */
2246     }
2247   }
2248
2249   now.tv_usec += 40000; /* compensate for bad precision timers that might've
2250                            triggered too early */
2251   if(now.tv_usec >= 1000000) {
2252     now.tv_sec++;
2253     now.tv_usec -= 1000000;
2254   }
2255
2256   /*
2257    * The loop following here will go on as long as there are expire-times left
2258    * to process in the splay and 'data' will be re-assigned for every expired
2259    * handle we deal with.
2260    */
2261   do {
2262     /* the first loop lap 'data' can be NULL */
2263     if(data) {
2264       do
2265         result = multi_runsingle(multi, now, data->set.one_easy);
2266       while(CURLM_CALL_MULTI_PERFORM == result);
2267
2268       if(CURLM_OK >= result)
2269         /* get the socket(s) and check if the state has been changed since
2270            last */
2271         singlesocket(multi, data->set.one_easy);
2272     }
2273
2274     /* Check if there's one (more) expired timer to deal with! This function
2275        extracts a matching node if there is one */
2276
2277     multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2278     if(t) {
2279       data = t->payload; /* assign this for next loop */
2280       (void)add_next_timeout(now, multi, t->payload);
2281     }
2282
2283   } while(t);
2284
2285   *running_handles = multi->num_alive;
2286   return result;
2287 }
2288
2289 #undef curl_multi_setopt
2290 CURLMcode curl_multi_setopt(CURLM *multi_handle,
2291                             CURLMoption option, ...)
2292 {
2293   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
2294   CURLMcode res = CURLM_OK;
2295   va_list param;
2296
2297   if(!GOOD_MULTI_HANDLE(multi))
2298     return CURLM_BAD_HANDLE;
2299
2300   va_start(param, option);
2301
2302   switch(option) {
2303   case CURLMOPT_SOCKETFUNCTION:
2304     multi->socket_cb = va_arg(param, curl_socket_callback);
2305     break;
2306   case CURLMOPT_SOCKETDATA:
2307     multi->socket_userp = va_arg(param, void *);
2308     break;
2309   case CURLMOPT_PIPELINING:
2310     multi->pipelining_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
2311     break;
2312   case CURLMOPT_TIMERFUNCTION:
2313     multi->timer_cb = va_arg(param, curl_multi_timer_callback);
2314     break;
2315   case CURLMOPT_TIMERDATA:
2316     multi->timer_userp = va_arg(param, void *);
2317     break;
2318   case CURLMOPT_MAXCONNECTS:
2319     multi->maxconnects = va_arg(param, long);
2320     break;
2321   default:
2322     res = CURLM_UNKNOWN_OPTION;
2323     break;
2324   }
2325   va_end(param);
2326   return res;
2327 }
2328
2329 /* we define curl_multi_socket() in the public multi.h header */
2330 #undef curl_multi_socket
2331
2332 CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
2333                             int *running_handles)
2334 {
2335   CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
2336                                   0, running_handles);
2337   if(CURLM_OK >= result)
2338     update_timer((struct Curl_multi *)multi_handle);
2339   return result;
2340 }
2341
2342 CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
2343                                    int ev_bitmask, int *running_handles)
2344 {
2345   CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
2346                                   ev_bitmask, running_handles);
2347   if(CURLM_OK >= result)
2348     update_timer((struct Curl_multi *)multi_handle);
2349   return result;
2350 }
2351
2352 CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
2353
2354 {
2355   CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
2356                                   TRUE, CURL_SOCKET_BAD, 0, running_handles);
2357   if(CURLM_OK >= result)
2358     update_timer((struct Curl_multi *)multi_handle);
2359   return result;
2360 }
2361
2362 static CURLMcode multi_timeout(struct Curl_multi *multi,
2363                                long *timeout_ms)
2364 {
2365   static struct timeval tv_zero = {0,0};
2366
2367   if(multi->timetree) {
2368     /* we have a tree of expire times */
2369     struct timeval now = Curl_tvnow();
2370
2371     /* splay the lowest to the bottom */
2372     multi->timetree = Curl_splay(tv_zero, multi->timetree);
2373
2374     if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
2375       /* some time left before expiration */
2376       *timeout_ms = curlx_tvdiff(multi->timetree->key, now);
2377       if(!*timeout_ms)
2378         /*
2379          * Since we only provide millisecond resolution on the returned value
2380          * and the diff might be less than one millisecond here, we don't
2381          * return zero as that may cause short bursts of busyloops on fast
2382          * processors while the diff is still present but less than one
2383          * millisecond! instead we return 1 until the time is ripe.
2384          */
2385         *timeout_ms=1;
2386     }
2387     else
2388       /* 0 means immediately */
2389       *timeout_ms = 0;
2390   }
2391   else
2392     *timeout_ms = -1;
2393
2394   return CURLM_OK;
2395 }
2396
2397 CURLMcode curl_multi_timeout(CURLM *multi_handle,
2398                              long *timeout_ms)
2399 {
2400   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
2401
2402   /* First, make some basic checks that the CURLM handle is a good handle */
2403   if(!GOOD_MULTI_HANDLE(multi))
2404     return CURLM_BAD_HANDLE;
2405
2406   return multi_timeout(multi, timeout_ms);
2407 }
2408
2409 /*
2410  * Tell the application it should update its timers, if it subscribes to the
2411  * update timer callback.
2412  */
2413 static int update_timer(struct Curl_multi *multi)
2414 {
2415   long timeout_ms;
2416
2417   if(!multi->timer_cb)
2418     return 0;
2419   if(multi_timeout(multi, &timeout_ms)) {
2420     return -1;
2421   }
2422   if(timeout_ms < 0) {
2423     static const struct timeval none={0,0};
2424     if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
2425       multi->timer_lastcall = none;
2426       /* there's no timeout now but there was one previously, tell the app to
2427          disable it */
2428       return multi->timer_cb((CURLM*)multi, -1, multi->timer_userp);
2429     }
2430     return 0;
2431   }
2432
2433   /* When multi_timeout() is done, multi->timetree points to the node with the
2434    * timeout we got the (relative) time-out time for. We can thus easily check
2435    * if this is the same (fixed) time as we got in a previous call and then
2436    * avoid calling the callback again. */
2437   if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
2438     return 0;
2439
2440   multi->timer_lastcall = multi->timetree->key;
2441
2442   return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
2443 }
2444
2445 static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
2446                                               struct connectdata *conn)
2447 {
2448   size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
2449   struct curl_llist_element *sendhead = conn->send_pipe->head;
2450   struct curl_llist *pipeline;
2451   CURLcode rc;
2452
2453   if(!Curl_isPipeliningEnabled(handle) ||
2454      pipeLen == 0)
2455     pipeline = conn->send_pipe;
2456   else {
2457     if(conn->server_supports_pipelining &&
2458        pipeLen < MAX_PIPELINE_LENGTH)
2459       pipeline = conn->send_pipe;
2460     else
2461       pipeline = conn->pend_pipe;
2462   }
2463
2464   rc = Curl_addHandleToPipeline(handle, pipeline);
2465
2466   if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
2467     /* this is a new one as head, expire it */
2468     conn->writechannel_inuse = FALSE; /* not in use yet */
2469 #ifdef DEBUGBUILD
2470     infof(conn->data, "%p is at send pipe head!\n",
2471           conn->send_pipe->head->ptr);
2472 #endif
2473     Curl_expire(conn->send_pipe->head->ptr, 1);
2474   }
2475
2476   return rc;
2477 }
2478
2479 static int checkPendPipeline(struct connectdata *conn)
2480 {
2481   int result = 0;
2482   struct curl_llist_element *sendhead = conn->send_pipe->head;
2483
2484   size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
2485   if(conn->server_supports_pipelining || pipeLen == 0) {
2486     struct curl_llist_element *curr = conn->pend_pipe->head;
2487     const size_t maxPipeLen =
2488       conn->server_supports_pipelining ? MAX_PIPELINE_LENGTH : 1;
2489
2490     while(pipeLen < maxPipeLen && curr) {
2491       Curl_llist_move(conn->pend_pipe, curr,
2492                       conn->send_pipe, conn->send_pipe->tail);
2493       Curl_pgrsTime(curr->ptr, TIMER_PRETRANSFER);
2494       ++result; /* count how many handles we moved */
2495       curr = conn->pend_pipe->head;
2496       ++pipeLen;
2497     }
2498   }
2499
2500   if(result) {
2501     conn->now = Curl_tvnow();
2502     /* something moved, check for a new send pipeline leader */
2503     if(sendhead != conn->send_pipe->head) {
2504       /* this is a new one as head, expire it */
2505       conn->writechannel_inuse = FALSE; /* not in use yet */
2506 #ifdef DEBUGBUILD
2507       infof(conn->data, "%p is at send pipe head!\n",
2508             conn->send_pipe->head->ptr);
2509 #endif
2510       Curl_expire(conn->send_pipe->head->ptr, 1);
2511     }
2512   }
2513
2514   return result;
2515 }
2516
2517 /* Move this transfer from the sending list to the receiving list.
2518
2519    Pay special attention to the new sending list "leader" as it needs to get
2520    checked to update what sockets it acts on.
2521
2522 */
2523 static void moveHandleFromSendToRecvPipeline(struct SessionHandle *handle,
2524                                              struct connectdata *conn)
2525 {
2526   struct curl_llist_element *curr;
2527
2528   curr = conn->send_pipe->head;
2529   while(curr) {
2530     if(curr->ptr == handle) {
2531       Curl_llist_move(conn->send_pipe, curr,
2532                       conn->recv_pipe, conn->recv_pipe->tail);
2533
2534       if(conn->send_pipe->head) {
2535         /* Since there's a new easy handle at the start of the send pipeline,
2536            set its timeout value to 1ms to make it trigger instantly */
2537         conn->writechannel_inuse = FALSE; /* not used now */
2538 #ifdef DEBUGBUILD
2539         infof(conn->data, "%p is at send pipe head B!\n",
2540               conn->send_pipe->head->ptr);
2541 #endif
2542         Curl_expire(conn->send_pipe->head->ptr, 1);
2543       }
2544
2545       /* The receiver's list is not really interesting here since either this
2546          handle is now first in the list and we'll deal with it soon, or
2547          another handle is already first and thus is already taken care of */
2548
2549       break; /* we're done! */
2550     }
2551     curr = curr->next;
2552   }
2553 }
2554
2555 static void moveHandleFromRecvToDonePipeline(struct SessionHandle *handle,
2556                                             struct connectdata *conn)
2557 {
2558   struct curl_llist_element *curr;
2559
2560   curr = conn->recv_pipe->head;
2561   while(curr) {
2562     if(curr->ptr == handle) {
2563       Curl_llist_move(conn->recv_pipe, curr,
2564                       conn->done_pipe, conn->done_pipe->tail);
2565       break;
2566     }
2567     curr = curr->next;
2568   }
2569 }
2570 static bool isHandleAtHead(struct SessionHandle *handle,
2571                            struct curl_llist *pipeline)
2572 {
2573   struct curl_llist_element *curr = pipeline->head;
2574   if(curr)
2575     return (curr->ptr == handle) ? TRUE : FALSE;
2576
2577   return FALSE;
2578 }
2579
2580 /*
2581  * multi_freetimeout()
2582  *
2583  * Callback used by the llist system when a single timeout list entry is
2584  * destroyed.
2585  */
2586 static void multi_freetimeout(void *user, void *entryptr)
2587 {
2588   (void)user;
2589
2590   /* the entry was plain malloc()'ed */
2591   free(entryptr);
2592 }
2593
2594 /*
2595  * multi_addtimeout()
2596  *
2597  * Add a timestamp to the list of timeouts. Keep the list sorted so that head
2598  * of list is always the timeout nearest in time.
2599  *
2600  */
2601 static CURLMcode
2602 multi_addtimeout(struct curl_llist *timeoutlist,
2603                  struct timeval *stamp)
2604 {
2605   struct curl_llist_element *e;
2606   struct timeval *timedup;
2607   struct curl_llist_element *prev = NULL;
2608
2609   timedup = malloc(sizeof(*timedup));
2610   if(!timedup)
2611     return CURLM_OUT_OF_MEMORY;
2612
2613   /* copy the timestamp */
2614   memcpy(timedup, stamp, sizeof(*timedup));
2615
2616   if(Curl_llist_count(timeoutlist)) {
2617     /* find the correct spot in the list */
2618     for(e = timeoutlist->head; e; e = e->next) {
2619       struct timeval *checktime = e->ptr;
2620       long diff = curlx_tvdiff(*checktime, *timedup);
2621       if(diff > 0)
2622         break;
2623       prev = e;
2624     }
2625
2626   }
2627   /* else
2628      this is the first timeout on the list */
2629
2630   if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
2631     free(timedup);
2632     return CURLM_OUT_OF_MEMORY;
2633   }
2634
2635   return CURLM_OK;
2636 }
2637
2638 /*
2639  * Curl_expire()
2640  *
2641  * given a number of milliseconds from now to use to set the 'act before
2642  * this'-time for the transfer, to be extracted by curl_multi_timeout()
2643  *
2644  * Note that the timeout will be added to a queue of timeouts if it defines a
2645  * moment in time that is later than the current head of queue.
2646  *
2647  * Pass zero to clear all timeout values for this handle.
2648 */
2649 void Curl_expire(struct SessionHandle *data, long milli)
2650 {
2651   struct Curl_multi *multi = data->multi;
2652   struct timeval *nowp = &data->state.expiretime;
2653   int rc;
2654
2655   /* this is only interesting for multi-interface using libcurl, and only
2656      while there is still a multi interface struct remaining! */
2657   if(!multi)
2658     return;
2659
2660   if(!milli) {
2661     /* No timeout, clear the time data. */
2662     if(nowp->tv_sec || nowp->tv_usec) {
2663       /* Since this is an cleared time, we must remove the previous entry from
2664          the splay tree */
2665       struct curl_llist *list = data->state.timeoutlist;
2666
2667       rc = Curl_splayremovebyaddr(multi->timetree,
2668                                   &data->state.timenode,
2669                                   &multi->timetree);
2670       if(rc)
2671         infof(data, "Internal error clearing splay node = %d\n", rc);
2672
2673       /* flush the timeout list too */
2674       while(list->size > 0)
2675         Curl_llist_remove(list, list->tail, NULL);
2676
2677 #ifdef DEBUGBUILD
2678       infof(data, "Expire cleared\n");
2679 #endif
2680       nowp->tv_sec = 0;
2681       nowp->tv_usec = 0;
2682     }
2683   }
2684   else {
2685     struct timeval set;
2686
2687     set = Curl_tvnow();
2688     set.tv_sec += milli/1000;
2689     set.tv_usec += (milli%1000)*1000;
2690
2691     if(set.tv_usec >= 1000000) {
2692       set.tv_sec++;
2693       set.tv_usec -= 1000000;
2694     }
2695
2696     if(nowp->tv_sec || nowp->tv_usec) {
2697       /* This means that the struct is added as a node in the splay tree.
2698          Compare if the new time is earlier, and only remove-old/add-new if it
2699          is. */
2700       long diff = curlx_tvdiff(set, *nowp);
2701       if(diff > 0) {
2702         /* the new expire time was later so just add it to the queue
2703            and get out */
2704         multi_addtimeout(data->state.timeoutlist, &set);
2705         return;
2706       }
2707
2708       /* the new time is newer than the presently set one, so add the current
2709          to the queue and update the head */
2710       multi_addtimeout(data->state.timeoutlist, nowp);
2711
2712       /* Since this is an updated time, we must remove the previous entry from
2713          the splay tree first and then re-add the new value */
2714       rc = Curl_splayremovebyaddr(multi->timetree,
2715                                   &data->state.timenode,
2716                                   &multi->timetree);
2717       if(rc)
2718         infof(data, "Internal error removing splay node = %d\n", rc);
2719     }
2720
2721     *nowp = set;
2722     data->state.timenode.payload = data;
2723     multi->timetree = Curl_splayinsert(*nowp,
2724                                        multi->timetree,
2725                                        &data->state.timenode);
2726   }
2727 #if 0
2728   Curl_splayprint(multi->timetree, 0, TRUE);
2729 #endif
2730 }
2731
2732 CURLMcode curl_multi_assign(CURLM *multi_handle,
2733                             curl_socket_t s, void *hashp)
2734 {
2735   struct Curl_sh_entry *there = NULL;
2736   struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
2737
2738   if(s != CURL_SOCKET_BAD)
2739     there = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(curl_socket_t));
2740
2741   if(!there)
2742     return CURLM_BAD_SOCKET;
2743
2744   there->socketp = hashp;
2745
2746   return CURLM_OK;
2747 }
2748
2749 #ifdef DEBUGBUILD
2750 void Curl_multi_dump(const struct Curl_multi *multi_handle)
2751 {
2752   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
2753   struct Curl_one_easy *easy;
2754   int i;
2755   fprintf(stderr, "* Multi status: %d handles, %d alive\n",
2756           multi->num_easy, multi->num_alive);
2757   for(easy=multi->easy.next; easy != &multi->easy; easy = easy->next) {
2758     if(easy->state < CURLM_STATE_COMPLETED) {
2759       /* only display handles that are not completed */
2760       fprintf(stderr, "handle %p, state %s, %d sockets\n",
2761               (void *)easy->easy_handle,
2762               statename[easy->state], easy->numsocks);
2763       for(i=0; i < easy->numsocks; i++) {
2764         curl_socket_t s = easy->sockets[i];
2765         struct Curl_sh_entry *entry =
2766           Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
2767
2768         fprintf(stderr, "%d ", (int)s);
2769         if(!entry) {
2770           fprintf(stderr, "INTERNAL CONFUSION\n");
2771           continue;
2772         }
2773         fprintf(stderr, "[%s %s] ",
2774                 entry->action&CURL_POLL_IN?"RECVING":"",
2775                 entry->action&CURL_POLL_OUT?"SENDING":"");
2776       }
2777       if(easy->numsocks)
2778         fprintf(stderr, "\n");
2779     }
2780   }
2781 }
2782 #endif