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