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