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