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