1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
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 https://curl.haxx.se/docs/copyright.html.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #include <curl/curl.h>
40 #include "speedcheck.h"
41 #include "conncache.h"
42 #include "multihandle.h"
45 /* The last 3 #include files should be in this order */
46 #include "curl_printf.h"
47 #include "curl_memory.h"
51 CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
52 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
53 CURL handle takes 45-50 K memory, therefore this 3K are not significant.
55 #ifndef CURL_SOCKET_HASH_TABLE_SIZE
56 #define CURL_SOCKET_HASH_TABLE_SIZE 911
59 #define CURL_CONNECTION_HASH_SIZE 97
61 #define CURL_MULTI_HANDLE 0x000bab1e
63 #define GOOD_MULTI_HANDLE(x) \
64 ((x) && (x)->type == CURL_MULTI_HANDLE)
66 static void singlesocket(struct Curl_multi *multi,
67 struct Curl_easy *data);
68 static int update_timer(struct Curl_multi *multi);
70 static CURLMcode add_next_timeout(struct timeval now,
71 struct Curl_multi *multi,
73 static CURLMcode multi_timeout(struct Curl_multi *multi,
77 static const char * const statename[]={
100 static void multi_freetimeout(void *a, void *b);
102 /* function pointer called once when switching TO a state */
103 typedef void (*init_multistate_func)(struct Curl_easy *data);
105 /* always use this function to change state, to make debugging easier */
106 static void mstate(struct Curl_easy *data, CURLMstate state
112 CURLMstate oldstate = data->mstate;
113 static const init_multistate_func finit[CURLM_STATE_LAST] = {
116 Curl_init_CONNECT, /* CONNECT */
117 /* the rest is NULL too */
120 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
124 if(oldstate == state)
125 /* don't bother when the new state is the same as the old state */
128 data->mstate = state;
130 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
131 if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
132 data->mstate < CURLM_STATE_COMPLETED) {
133 long connection_id = -5000;
136 connection_id = data->easy_conn->connection_id;
139 "STATE: %s => %s handle %p; line %d (connection #%ld)\n",
140 statename[oldstate], statename[data->mstate],
141 (void *)data, lineno, connection_id);
145 if(state == CURLM_STATE_COMPLETED)
146 /* changing to COMPLETED means there's one less easy handle 'alive' */
147 data->multi->num_alive--;
149 /* if this state has an init-function, run it */
155 #define multistate(x,y) mstate(x,y)
157 #define multistate(x,y) mstate(x,y, __LINE__)
161 * We add one of these structs to the sockhash for a particular socket
164 struct Curl_sh_entry {
165 struct Curl_easy *easy;
166 int action; /* what action READ/WRITE this socket waits for */
167 curl_socket_t socket; /* mainly to ease debugging */
168 void *socketp; /* settable by users with curl_multi_assign() */
170 /* bits for 'action' having no bits means this socket is not expecting any
175 /* look up a given socket in the socket hash, skip invalid sockets */
176 static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
179 if(s != CURL_SOCKET_BAD)
180 /* only look for proper sockets */
181 return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
185 /* make sure this socket is present in the hash for this handle */
186 static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
188 struct Curl_easy *data)
190 struct Curl_sh_entry *there = sh_getentry(sh, s);
191 struct Curl_sh_entry *check;
194 /* it is present, return fine */
197 /* not present, add it */
198 check = calloc(1, sizeof(struct Curl_sh_entry));
200 return NULL; /* major failure */
205 /* make/add new hash entry */
206 if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
208 return NULL; /* major failure */
211 return check; /* things are good in sockhash land */
215 /* delete the given socket + handle from the hash */
216 static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
218 /* We remove the hash entry. This will end up in a call to
220 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
224 * free a sockhash entry
226 static void sh_freeentry(void *freethis)
228 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
233 static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
235 (void) k1_len; (void) k2_len;
237 return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2));
240 static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
242 curl_socket_t fd = *((curl_socket_t *) key);
245 return (fd % slots_num);
249 * sh_init() creates a new socket hash and returns the handle for it.
251 * Quote from README.multi_socket:
253 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
254 * is somewhat of a bottle neck. Its current implementation may be a bit too
255 * limiting. It simply has a fixed-size array, and on each entry in the array
256 * it has a linked list with entries. So the hash only checks which list to
257 * scan through. The code I had used so for used a list with merely 7 slots
258 * (as that is what the DNS hash uses) but with 7000 connections that would
259 * make an average of 1000 nodes in each list to run through. I upped that to
260 * 97 slots (I believe a prime is suitable) and noticed a significant speed
261 * increase. I need to reconsider the hash implementation or use a rather
262 * large default value like this. At 9000 connections I was still below 10us
266 static int sh_init(struct curl_hash *hash, int hashsize)
268 return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
275 * Called when a transfer is completed. Adds the given msg pointer to
276 * the list kept in the multi handle.
278 static CURLMcode multi_addmsg(struct Curl_multi *multi,
279 struct Curl_message *msg)
281 if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
282 return CURLM_OUT_OF_MEMORY;
290 * Callback used by the llist system when a single list entry is destroyed.
292 static void multi_freeamsg(void *a, void *b)
298 struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
299 int chashsize) /* connection hash */
301 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
306 multi->type = CURL_MULTI_HANDLE;
308 if(Curl_mk_dnscache(&multi->hostcache))
311 if(sh_init(&multi->sockhash, hashsize))
314 if(Curl_conncache_init(&multi->conn_cache, chashsize))
317 multi->msglist = Curl_llist_alloc(multi_freeamsg);
321 multi->pending = Curl_llist_alloc(multi_freeamsg);
325 /* allocate a new easy handle to use when closing cached connections */
326 multi->closure_handle = curl_easy_init();
327 if(!multi->closure_handle)
330 multi->closure_handle->multi = multi;
331 multi->closure_handle->state.conn_cache = &multi->conn_cache;
333 multi->max_pipeline_length = 5;
335 /* -1 means it not set by user, use the default value */
336 multi->maxconnects = -1;
341 Curl_hash_destroy(&multi->sockhash);
342 Curl_hash_destroy(&multi->hostcache);
343 Curl_conncache_destroy(&multi->conn_cache);
344 Curl_close(multi->closure_handle);
345 multi->closure_handle = NULL;
346 Curl_llist_destroy(multi->msglist, NULL);
347 Curl_llist_destroy(multi->pending, NULL);
353 struct Curl_multi *curl_multi_init(void)
355 return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
356 CURL_CONNECTION_HASH_SIZE);
359 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
360 struct Curl_easy *data)
362 struct curl_llist *timeoutlist;
364 /* First, make some basic checks that the CURLM handle is a good handle */
365 if(!GOOD_MULTI_HANDLE(multi))
366 return CURLM_BAD_HANDLE;
368 /* Verify that we got a somewhat good easy handle too */
369 if(!GOOD_EASY_HANDLE(data))
370 return CURLM_BAD_EASY_HANDLE;
372 /* Prevent users from adding same easy handle more than once and prevent
373 adding to more than one multi stack */
375 return CURLM_ADDED_ALREADY;
377 /* Allocate and initialize timeout list for easy handle */
378 timeoutlist = Curl_llist_alloc(multi_freetimeout);
380 return CURLM_OUT_OF_MEMORY;
383 * No failure allowed in this function beyond this point. And no
384 * modification of easy nor multi handle allowed before this except for
385 * potential multi's connection cache growing which won't be undone in this
386 * function no matter what.
389 /* Make easy handle use timeout list initialized above */
390 data->state.timeoutlist = timeoutlist;
393 /* set the easy handle */
394 multistate(data, CURLM_STATE_INIT);
396 if((data->set.global_dns_cache) &&
397 (data->dns.hostcachetype != HCACHE_GLOBAL)) {
398 /* global dns cache was requested but still isn't */
399 struct curl_hash *global = Curl_global_host_cache_init();
401 /* only do this if the global cache init works */
402 data->dns.hostcache = global;
403 data->dns.hostcachetype = HCACHE_GLOBAL;
406 /* for multi interface connections, we share DNS cache automatically if the
407 easy handle's one is currently not set. */
408 else if(!data->dns.hostcache ||
409 (data->dns.hostcachetype == HCACHE_NONE)) {
410 data->dns.hostcache = &multi->hostcache;
411 data->dns.hostcachetype = HCACHE_MULTI;
414 /* Point to the multi's connection cache */
415 data->state.conn_cache = &multi->conn_cache;
417 /* This adds the new entry at the 'end' of the doubly-linked circular
418 list of Curl_easy structs to try and maintain a FIFO queue so
419 the pipelined requests are in order. */
421 /* We add this new entry last in the list. */
423 data->next = NULL; /* end of the line */
425 struct Curl_easy *last = multi->easylp;
428 multi->easylp = data; /* the new last node */
431 /* first node, make prev NULL! */
433 multi->easylp = multi->easyp = data; /* both first and last */
436 /* make the Curl_easy refer back to this multi handle */
439 /* Set the timeout for this handle to expire really soon so that it will
440 be taken care of even when this handle is added in the midst of operation
441 when only the curl_multi_socket() API is used. During that flow, only
442 sockets that time-out or have actions will be dealt with. Since this
443 handle has no action yet, we make sure it times out to get things to
445 Curl_expire(data, 0);
447 /* increase the node-counter */
450 /* increase the alive-counter */
453 /* A somewhat crude work-around for a little glitch in update_timer() that
454 happens if the lastcall time is set to the same time when the handle is
455 removed as when the next handle is added, as then the check in
456 update_timer() that prevents calling the application multiple times with
457 the same timer infor will not trigger and then the new handle's timeout
458 will not be notified to the app.
460 The work-around is thus simply to clear the 'lastcall' variable to force
461 update_timer() to always trigger a callback to the app when a new easy
463 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
470 /* Debug-function, used like this:
472 * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
474 * Enable the hash print function first by editing hash.c
476 static void debug_print_sock_hash(void *p)
478 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
480 fprintf(stderr, " [easy %p/magic %x/socket %d]",
481 (void *)sh->data, sh->data->magic, (int)sh->socket);
485 /* Mark the connection as 'idle', or close it if the cache is full.
486 Returns TRUE if the connection is kept, or FALSE if it was closed. */
488 ConnectionDone(struct Curl_easy *data, struct connectdata *conn)
490 /* data->multi->maxconnects can be negative, deal with it. */
492 (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
493 data->multi->maxconnects;
494 struct connectdata *conn_candidate = NULL;
496 /* Mark the current connection as 'unused' */
499 if(maxconnects > 0 &&
500 data->state.conn_cache->num_connections > maxconnects) {
501 infof(data, "Connection cache is full, closing the oldest one.\n");
503 conn_candidate = Curl_oldest_idle_connection(data);
506 /* Set the connection's owner correctly */
507 conn_candidate->data = data;
509 /* the winner gets the honour of being disconnected */
510 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
514 return (conn_candidate == conn) ? FALSE : TRUE;
517 static CURLcode multi_done(struct connectdata **connp,
518 CURLcode status, /* an error if this is called
519 after an error was detected */
523 struct connectdata *conn;
524 struct Curl_easy *data;
531 DEBUGF(infof(data, "multi_done\n"));
534 /* Stop if multi_done() has already been called */
537 Curl_getoff_all_pipelines(data, conn);
539 /* Cleanup possible redirect junk */
540 free(data->req.newurl);
541 data->req.newurl = NULL;
542 free(data->req.location);
543 data->req.location = NULL;
546 case CURLE_ABORTED_BY_CALLBACK:
547 case CURLE_READ_ERROR:
548 case CURLE_WRITE_ERROR:
549 /* When we're aborted due to a callback return code it basically have to
550 be counted as premature as there is trouble ahead if we don't. We have
551 many callbacks and protocols work differently, we could potentially do
552 this more fine-grained in the future. */
558 /* this calls the protocol-specific function pointer previously set */
559 if(conn->handler->done)
560 result = conn->handler->done(conn, status, premature);
564 if(CURLE_ABORTED_BY_CALLBACK != result) {
565 /* avoid this if we already aborted by callback to avoid this calling
567 CURLcode rc = Curl_pgrsDone(conn);
569 result = CURLE_ABORTED_BY_CALLBACK;
572 if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
573 !data->set.reuse_forbid &&
575 /* Stop if pipeline is not empty and we do not have to close
577 DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
581 data->state.done = TRUE; /* called just now! */
582 Curl_resolver_cancel(conn);
584 if(conn->dns_entry) {
585 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
586 conn->dns_entry = NULL;
589 /* if the transfer was completed in a paused state there can be buffered
590 data left to write and then kill */
591 free(data->state.tempwrite);
592 data->state.tempwrite = NULL;
594 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
595 forced us to close this connection. This is ignored for requests taking
596 place in a NTLM authentication handshake
598 if conn->bits.close is TRUE, it means that the connection should be
599 closed in spite of all our efforts to be nice, due to protocol
600 restrictions in our or the server's end
602 if premature is TRUE, it means this connection was said to be DONE before
603 the entire request operation is complete and thus we can't know in what
604 state it is for re-using, so we're forced to close it. In a perfect world
605 we can add code that keep track of if we really must close it here or not,
606 but currently we have no such detail knowledge.
609 if((data->set.reuse_forbid
610 #if defined(USE_NTLM)
611 && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
612 conn->proxyntlm.state == NTLMSTATE_TYPE2)
614 ) || conn->bits.close || premature) {
615 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
617 /* If we had an error already, make sure we return that one. But
618 if we got a new error, return that. */
623 /* the connection is no longer in use */
624 if(ConnectionDone(data, conn)) {
625 /* remember the most recently used connection */
626 data->state.lastconnect = conn;
628 infof(data, "Connection #%ld to host %s left intact\n",
630 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
633 data->state.lastconnect = NULL;
636 *connp = NULL; /* to make the caller of this function better detect that
637 this was either closed or handed over to the connection
638 cache here, and therefore cannot be used from this point on
640 Curl_free_request_state(data);
645 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
646 struct Curl_easy *data)
648 struct Curl_easy *easy = data;
651 struct curl_llist_element *e;
653 /* First, make some basic checks that the CURLM handle is a good handle */
654 if(!GOOD_MULTI_HANDLE(multi))
655 return CURLM_BAD_HANDLE;
657 /* Verify that we got a somewhat good easy handle too */
658 if(!GOOD_EASY_HANDLE(data))
659 return CURLM_BAD_EASY_HANDLE;
661 /* Prevent users from trying to remove same easy handle more than once */
663 return CURLM_OK; /* it is already removed so let's say it is fine! */
665 premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
666 easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
669 /* If the 'state' is not INIT or COMPLETED, we might need to do something
670 nice to put the easy_handle in a good known state when this returns. */
672 /* this handle is "alive" so we need to count down the total number of
673 alive connections when this is removed */
676 /* When this handle gets removed, other handles may be able to get the
678 Curl_multi_process_pending_handles(multi);
681 if(data->easy_conn &&
682 data->mstate > CURLM_STATE_DO &&
683 data->mstate < CURLM_STATE_COMPLETED) {
684 /* If the handle is in a pipeline and has started sending off its
685 request but not received its response yet, we need to close
687 streamclose(data->easy_conn, "Removed with partial response");
688 /* Set connection owner so that the DONE function closes it. We can
689 safely do this here since connection is killed. */
690 data->easy_conn->data = easy;
691 easy_owns_conn = TRUE;
694 /* The timer must be shut down before data->multi is set to NULL,
695 else the timenode will remain in the splay tree after
696 curl_easy_cleanup is called. */
697 Curl_expire_clear(data);
699 if(data->dns.hostcachetype == HCACHE_MULTI) {
700 /* stop using the multi handle's DNS cache */
701 data->dns.hostcache = NULL;
702 data->dns.hostcachetype = HCACHE_NONE;
705 if(data->easy_conn) {
707 /* we must call multi_done() here (if we still own the connection) so that
708 we don't leave a half-baked one around */
711 /* multi_done() clears the conn->data field to lose the association
712 between the easy handle and the connection
714 Note that this ignores the return code simply because there's
715 nothing really useful to do with it anyway! */
716 (void)multi_done(&data->easy_conn, data->result, premature);
719 /* Clear connection pipelines, if multi_done above was not called */
720 Curl_getoff_all_pipelines(data, data->easy_conn);
723 Curl_wildcard_dtor(&data->wildcard);
725 /* destroy the timeout list that is held in the easy handle, do this *after*
726 multi_done() as that may actually call Curl_expire that uses this */
727 if(data->state.timeoutlist) {
728 Curl_llist_destroy(data->state.timeoutlist, NULL);
729 data->state.timeoutlist = NULL;
732 /* as this was using a shared connection cache we clear the pointer to that
733 since we're not part of that multi handle anymore */
734 data->state.conn_cache = NULL;
736 /* change state without using multistate(), only to make singlesocket() do
738 data->mstate = CURLM_STATE_COMPLETED;
739 singlesocket(multi, easy); /* to let the application know what sockets that
740 vanish with this handle */
742 /* Remove the association between the connection and the handle */
743 if(data->easy_conn) {
744 data->easy_conn->data = NULL;
745 data->easy_conn = NULL;
748 data->multi = NULL; /* clear the association to this multi handle */
750 /* make sure there's no pending message in the queue sent from this easy
753 for(e = multi->msglist->head; e; e = e->next) {
754 struct Curl_message *msg = e->ptr;
756 if(msg->extmsg.easy_handle == easy) {
757 Curl_llist_remove(multi->msglist, e, NULL);
758 /* there can only be one from this specific handle */
763 /* make the previous node point to our next */
765 data->prev->next = data->next;
767 multi->easyp = data->next; /* point to first node */
769 /* make our next point to our previous node */
771 data->next->prev = data->prev;
773 multi->easylp = data->prev; /* point to last node */
776 We do not touch the easy handle here! */
777 multi->num_easy--; /* one less to care about now */
783 /* Return TRUE if the application asked for a certain set of pipelining */
784 bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
786 return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
789 void Curl_multi_handlePipeBreak(struct Curl_easy *data)
791 data->easy_conn = NULL;
794 static int waitconnect_getsock(struct connectdata *conn,
803 return GETSOCK_BLANK;
806 if(conn->tempsock[i] != CURL_SOCKET_BAD) {
807 sock[s] = conn->tempsock[i];
808 rc |= GETSOCK_WRITESOCK(s++);
815 static int waitproxyconnect_getsock(struct connectdata *conn,
820 return GETSOCK_BLANK;
822 sock[0] = conn->sock[FIRSTSOCKET];
824 /* when we've sent a CONNECT to a proxy, we should rather wait for the
825 socket to become readable to be able to get the response headers */
826 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
827 return GETSOCK_READSOCK(0);
829 return GETSOCK_WRITESOCK(0);
832 static int domore_getsock(struct connectdata *conn,
833 curl_socket_t *socks,
836 if(conn && conn->handler->domore_getsock)
837 return conn->handler->domore_getsock(conn, socks, numsocks);
838 return GETSOCK_BLANK;
841 /* returns bitmapped flags for this handle and its sockets */
842 static int multi_getsock(struct Curl_easy *data,
843 curl_socket_t *socks, /* points to numsocks number
847 /* If the pipe broke, or if there's no connection left for this easy handle,
848 then we MUST bail out now with no bitmask set. The no connection case can
849 happen when this is called from curl_multi_remove_handle() =>
850 singlesocket() => multi_getsock().
852 if(data->state.pipe_broke || !data->easy_conn)
855 if(data->mstate > CURLM_STATE_CONNECT &&
856 data->mstate < CURLM_STATE_COMPLETED) {
857 /* Set up ownership correctly */
858 data->easy_conn->data = data;
861 switch(data->mstate) {
863 #if 0 /* switch back on these cases to get the compiler to check for all enums
865 case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
866 case CURLM_STATE_COMPLETED:
867 case CURLM_STATE_MSGSENT:
868 case CURLM_STATE_INIT:
869 case CURLM_STATE_CONNECT:
870 case CURLM_STATE_WAITDO:
871 case CURLM_STATE_DONE:
872 case CURLM_STATE_LAST:
873 /* this will get called with CURLM_STATE_COMPLETED when a handle is
878 case CURLM_STATE_WAITRESOLVE:
879 return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
881 case CURLM_STATE_PROTOCONNECT:
882 case CURLM_STATE_SENDPROTOCONNECT:
883 return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
886 case CURLM_STATE_DOING:
887 return Curl_doing_getsock(data->easy_conn, socks, numsocks);
889 case CURLM_STATE_WAITPROXYCONNECT:
890 return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
892 case CURLM_STATE_WAITCONNECT:
893 return waitconnect_getsock(data->easy_conn, socks, numsocks);
895 case CURLM_STATE_DO_MORE:
896 return domore_getsock(data->easy_conn, socks, numsocks);
898 case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
899 to waiting for the same as the *PERFORM
901 case CURLM_STATE_PERFORM:
902 case CURLM_STATE_WAITPERFORM:
903 return Curl_single_getsock(data->easy_conn, socks, numsocks);
908 CURLMcode curl_multi_fdset(struct Curl_multi *multi,
909 fd_set *read_fd_set, fd_set *write_fd_set,
910 fd_set *exc_fd_set, int *max_fd)
912 /* Scan through all the easy handles to get the file descriptors set.
913 Some easy handles may not have connected to the remote host yet,
914 and then we must make sure that is done. */
915 struct Curl_easy *data;
917 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
920 (void)exc_fd_set; /* not used */
922 if(!GOOD_MULTI_HANDLE(multi))
923 return CURLM_BAD_HANDLE;
927 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
929 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
930 curl_socket_t s = CURL_SOCKET_BAD;
932 if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
933 FD_SET(sockbunch[i], read_fd_set);
936 if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
937 FD_SET(sockbunch[i], write_fd_set);
940 if(s == CURL_SOCKET_BAD)
941 /* this socket is unused, break out of loop */
944 if((int)s > this_max_fd)
945 this_max_fd = (int)s;
949 data = data->next; /* check next handle */
952 *max_fd = this_max_fd;
957 CURLMcode curl_multi_wait(struct Curl_multi *multi,
958 struct curl_waitfd extra_fds[],
959 unsigned int extra_nfds,
963 struct Curl_easy *data;
964 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
967 unsigned int nfds = 0;
968 unsigned int curlfds;
969 struct pollfd *ufds = NULL;
970 long timeout_internal;
973 if(!GOOD_MULTI_HANDLE(multi))
974 return CURLM_BAD_HANDLE;
976 /* If the internally desired timeout is actually shorter than requested from
977 the outside, then use the shorter time! But only if the internal timer
978 is actually larger than -1! */
979 (void)multi_timeout(multi, &timeout_internal);
980 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
981 timeout_ms = (int)timeout_internal;
983 /* Count up how many fds we have from the multi handle */
986 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
988 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
989 curl_socket_t s = CURL_SOCKET_BAD;
991 if(bitmap & GETSOCK_READSOCK(i)) {
995 if(bitmap & GETSOCK_WRITESOCK(i)) {
999 if(s == CURL_SOCKET_BAD) {
1004 data = data->next; /* check next handle */
1007 curlfds = nfds; /* number of internal file descriptors */
1008 nfds += extra_nfds; /* add the externally provided ones */
1010 if(nfds || extra_nfds) {
1011 ufds = malloc(nfds * sizeof(struct pollfd));
1013 return CURLM_OUT_OF_MEMORY;
1017 /* only do the second loop if we found descriptors in the first stage run
1021 /* Add the curl handles to our pollfds first */
1024 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1026 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1027 curl_socket_t s = CURL_SOCKET_BAD;
1029 if(bitmap & GETSOCK_READSOCK(i)) {
1030 ufds[nfds].fd = sockbunch[i];
1031 ufds[nfds].events = POLLIN;
1035 if(bitmap & GETSOCK_WRITESOCK(i)) {
1036 ufds[nfds].fd = sockbunch[i];
1037 ufds[nfds].events = POLLOUT;
1041 if(s == CURL_SOCKET_BAD) {
1046 data = data->next; /* check next handle */
1050 /* Add external file descriptions from poll-like struct curl_waitfd */
1051 for(i = 0; i < extra_nfds; i++) {
1052 ufds[nfds].fd = extra_fds[i].fd;
1053 ufds[nfds].events = 0;
1054 if(extra_fds[i].events & CURL_WAIT_POLLIN)
1055 ufds[nfds].events |= POLLIN;
1056 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1057 ufds[nfds].events |= POLLPRI;
1058 if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1059 ufds[nfds].events |= POLLOUT;
1066 pollrc = Curl_poll(ufds, nfds, timeout_ms);
1067 DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
1068 nfds, timeout_ms, pollrc));
1072 /* copy revents results from the poll to the curl_multi_wait poll
1073 struct, the bit values of the actual underlying poll() implementation
1074 may not be the same as the ones in the public libcurl API! */
1075 for(i = 0; i < extra_nfds; i++) {
1076 unsigned short mask = 0;
1077 unsigned r = ufds[curlfds + i].revents;
1080 mask |= CURL_WAIT_POLLIN;
1082 mask |= CURL_WAIT_POLLOUT;
1084 mask |= CURL_WAIT_POLLPRI;
1086 extra_fds[i].revents = mask;
1098 * Curl_multi_connchanged() is called to tell that there is a connection in
1099 * this multi handle that has changed state (pipelining become possible, the
1100 * number of allowed streams changed or similar), and a subsequent use of this
1101 * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1104 void Curl_multi_connchanged(struct Curl_multi *multi)
1106 multi->recheckstate = TRUE;
1110 * multi_ischanged() is called
1112 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1113 * => CONNECT action.
1115 * Set 'clear' to TRUE to have it also clear the state variable.
1117 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1119 bool retval = multi->recheckstate;
1121 multi->recheckstate = FALSE;
1125 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1126 struct Curl_easy *data,
1127 struct connectdata *conn)
1131 rc = curl_multi_add_handle(multi, data);
1133 struct SingleRequest *k = &data->req;
1135 /* pass in NULL for 'conn' here since we don't want to init the
1136 connection, only this transfer */
1137 Curl_init_do(data, NULL);
1139 /* take this handle to the perform state right away */
1140 multistate(data, CURLM_STATE_PERFORM);
1141 data->easy_conn = conn;
1142 k->keepon |= KEEP_RECV; /* setup to receive! */
1147 static CURLcode multi_reconnect_request(struct connectdata **connp)
1149 CURLcode result = CURLE_OK;
1150 struct connectdata *conn = *connp;
1151 struct Curl_easy *data = conn->data;
1153 /* This was a re-use of a connection and we got a write error in the
1154 * DO-phase. Then we DISCONNECT this connection and have another attempt to
1155 * CONNECT and then DO again! The retry cannot possibly find another
1156 * connection to re-use, since we only keep one possible connection for
1159 infof(data, "Re-used connection seems dead, get a new one\n");
1161 connclose(conn, "Reconnect dead connection"); /* enforce close */
1162 result = multi_done(&conn, result, FALSE); /* we are so done with this */
1164 /* conn may no longer be a good pointer, clear it to avoid mistakes by
1169 * We need to check for CURLE_SEND_ERROR here as well. This could happen
1170 * when the request failed on a FTP connection and thus multi_done() itself
1171 * tried to use the connection (again).
1173 if(!result || (CURLE_SEND_ERROR == result)) {
1175 bool protocol_done = TRUE;
1177 /* Now, redo the connect and get a new connection */
1178 result = Curl_connect(data, connp, &async, &protocol_done);
1180 /* We have connected or sent away a name resolve query fine */
1182 conn = *connp; /* setup conn to again point to something nice */
1184 /* Now, if async is TRUE here, we need to wait for the name
1186 result = Curl_resolver_wait_resolv(conn, NULL);
1190 /* Resolved, continue with the connection */
1191 result = Curl_async_resolved(conn, &protocol_done);
1202 * do_complete is called when the DO actions are complete.
1204 * We init chunking and trailer bits to their default values here immediately
1205 * before receiving any header data for the current request in the pipeline.
1207 static void do_complete(struct connectdata *conn)
1209 conn->data->req.chunk=FALSE;
1210 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
1211 conn->sockfd:conn->writesockfd)+1;
1212 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
1215 static CURLcode multi_do(struct connectdata **connp, bool *done)
1217 CURLcode result=CURLE_OK;
1218 struct connectdata *conn = *connp;
1219 struct Curl_easy *data = conn->data;
1221 if(conn->handler->do_it) {
1222 /* generic protocol-specific function pointer set in curl_connect() */
1223 result = conn->handler->do_it(conn, done);
1225 /* This was formerly done in transfer.c, but we better do it here */
1226 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
1228 * If the connection is using an easy handle, call reconnect
1229 * to re-establish the connection. Otherwise, let the multi logic
1230 * figure out how to re-establish the connection.
1233 result = multi_reconnect_request(connp);
1236 /* ... finally back to actually retry the DO phase */
1237 conn = *connp; /* re-assign conn since multi_reconnect_request
1238 creates a new connection */
1239 result = conn->handler->do_it(conn, done);
1246 if(!result && *done)
1247 /* do_complete must be called after the protocol-specific DO function */
1254 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1255 * second stage DO state which (wrongly) was introduced to support FTP's
1256 * second connection.
1258 * TODO: A future libcurl should be able to work away this state.
1260 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1261 * DOING state there's more work to do!
1264 static CURLcode multi_do_more(struct connectdata *conn, int *complete)
1266 CURLcode result=CURLE_OK;
1270 if(conn->handler->do_more)
1271 result = conn->handler->do_more(conn, complete);
1273 if(!result && (*complete == 1))
1274 /* do_complete must be called after the protocol-specific DO function */
1280 static CURLMcode multi_runsingle(struct Curl_multi *multi,
1282 struct Curl_easy *data)
1284 struct Curl_message *msg = NULL;
1287 bool protocol_connect = FALSE;
1288 bool dophase_done = FALSE;
1291 CURLcode result = CURLE_OK;
1292 struct SingleRequest *k;
1296 if(!GOOD_EASY_HANDLE(data))
1297 return CURLM_BAD_EASY_HANDLE;
1300 /* A "stream" here is a logical stream if the protocol can handle that
1301 (HTTP/2), or the full connection for older protocols */
1302 bool stream_error = FALSE;
1305 /* Handle the case when the pipe breaks, i.e., the connection
1306 we're using gets cleaned up and we're left with nothing. */
1307 if(data->state.pipe_broke) {
1308 infof(data, "Pipe broke: handle %p, url = %s\n",
1309 (void *)data, data->state.path);
1311 if(data->mstate < CURLM_STATE_COMPLETED) {
1312 /* Head back to the CONNECT state */
1313 multistate(data, CURLM_STATE_CONNECT);
1314 rc = CURLM_CALL_MULTI_PERFORM;
1318 data->state.pipe_broke = FALSE;
1319 data->easy_conn = NULL;
1323 if(!data->easy_conn &&
1324 data->mstate > CURLM_STATE_CONNECT &&
1325 data->mstate < CURLM_STATE_DONE) {
1326 /* In all these states, the code will blindly access 'data->easy_conn'
1327 so this is precaution that it isn't NULL. And it silences static
1329 failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
1330 return CURLM_INTERNAL_ERROR;
1333 if(multi_ischanged(multi, TRUE)) {
1334 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
1335 Curl_multi_process_pending_handles(multi);
1338 if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
1339 data->mstate < CURLM_STATE_COMPLETED)
1340 /* Make sure we set the connection's current owner */
1341 data->easy_conn->data = data;
1343 if(data->easy_conn &&
1344 (data->mstate >= CURLM_STATE_CONNECT) &&
1345 (data->mstate < CURLM_STATE_COMPLETED)) {
1346 /* we need to wait for the connect state as only then is the start time
1347 stored, but we must not check already completed handles */
1349 timeout_ms = Curl_timeleft(data, &now,
1350 (data->mstate <= CURLM_STATE_WAITDO)?
1353 if(timeout_ms < 0) {
1354 /* Handle timed out */
1355 if(data->mstate == CURLM_STATE_WAITRESOLVE)
1356 failf(data, "Resolving timed out after %ld milliseconds",
1357 Curl_tvdiff(now, data->progress.t_startsingle));
1358 else if(data->mstate == CURLM_STATE_WAITCONNECT)
1359 failf(data, "Connection timed out after %ld milliseconds",
1360 Curl_tvdiff(now, data->progress.t_startsingle));
1364 failf(data, "Operation timed out after %ld milliseconds with %"
1365 CURL_FORMAT_CURL_OFF_T " out of %"
1366 CURL_FORMAT_CURL_OFF_T " bytes received",
1367 Curl_tvdiff(now, data->progress.t_startsingle),
1368 k->bytecount, k->size);
1371 failf(data, "Operation timed out after %ld milliseconds with %"
1372 CURL_FORMAT_CURL_OFF_T " bytes received",
1373 Curl_tvdiff(now, data->progress.t_startsingle),
1378 /* Force connection closed if the connection has indeed been used */
1379 if(data->mstate > CURLM_STATE_DO) {
1380 streamclose(data->easy_conn, "Disconnected with pending data");
1381 stream_error = TRUE;
1383 result = CURLE_OPERATION_TIMEDOUT;
1384 (void)multi_done(&data->easy_conn, result, TRUE);
1385 /* Skip the statemachine and go directly to error handling section. */
1386 goto statemachine_end;
1390 switch(data->mstate) {
1391 case CURLM_STATE_INIT:
1392 /* init this transfer. */
1393 result=Curl_pretransfer(data);
1396 /* after init, go CONNECT */
1397 multistate(data, CURLM_STATE_CONNECT);
1398 Curl_pgrsTime(data, TIMER_STARTOP);
1399 rc = CURLM_CALL_MULTI_PERFORM;
1403 case CURLM_STATE_CONNECT_PEND:
1404 /* We will stay here until there is a connection available. Then
1405 we try again in the CURLM_STATE_CONNECT state. */
1408 case CURLM_STATE_CONNECT:
1409 /* Connect. We want to get a connection identifier filled in. */
1410 Curl_pgrsTime(data, TIMER_STARTSINGLE);
1411 result = Curl_connect(data, &data->easy_conn,
1412 &async, &protocol_connect);
1413 if(CURLE_NO_CONNECTION_AVAILABLE == result) {
1414 /* There was no connection available. We will go to the pending
1415 state and wait for an available connection. */
1416 multistate(data, CURLM_STATE_CONNECT_PEND);
1418 /* add this handle to the list of connect-pending handles */
1419 if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
1420 result = CURLE_OUT_OF_MEMORY;
1427 /* Add this handle to the send or pend pipeline */
1428 result = Curl_add_handle_to_pipeline(data, data->easy_conn);
1430 stream_error = TRUE;
1433 /* We're now waiting for an asynchronous name lookup */
1434 multistate(data, CURLM_STATE_WAITRESOLVE);
1436 /* after the connect has been sent off, go WAITCONNECT unless the
1437 protocol connect is already done and we can go directly to
1439 rc = CURLM_CALL_MULTI_PERFORM;
1441 if(protocol_connect)
1442 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1443 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1445 #ifndef CURL_DISABLE_HTTP
1446 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1447 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1450 multistate(data, CURLM_STATE_WAITCONNECT);
1457 case CURLM_STATE_WAITRESOLVE:
1458 /* awaiting an asynch name resolve to complete */
1460 struct Curl_dns_entry *dns = NULL;
1461 struct connectdata *conn = data->easy_conn;
1462 const char *hostname;
1464 if(conn->bits.proxy)
1465 hostname = conn->proxy.name;
1466 else if(conn->bits.conn_to_host)
1467 hostname = conn->conn_to_host.name;
1469 hostname = conn->host.name;
1471 /* check if we have the name resolved by now */
1472 dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
1475 #ifdef CURLRES_ASYNCH
1476 conn->async.dns = dns;
1477 conn->async.done = TRUE;
1480 infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
1484 result = Curl_resolver_is_resolved(data->easy_conn, &dns);
1486 /* Update sockets here, because the socket(s) may have been
1487 closed and the application thus needs to be told, even if it
1488 is likely that the same socket(s) will again be used further
1489 down. If the name has not yet been resolved, it is likely
1490 that new sockets have been opened in an attempt to contact
1491 another resolver. */
1492 singlesocket(multi, data);
1495 /* Perform the next step in the connection phase, and then move on
1496 to the WAITCONNECT state */
1497 result = Curl_async_resolved(data->easy_conn, &protocol_connect);
1500 /* if Curl_async_resolved() returns failure, the connection struct
1501 is already freed and gone */
1502 data->easy_conn = NULL; /* no more connection */
1504 /* call again please so that we get the next socket setup */
1505 rc = CURLM_CALL_MULTI_PERFORM;
1506 if(protocol_connect)
1507 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1508 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1510 #ifndef CURL_DISABLE_HTTP
1511 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1512 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1515 multistate(data, CURLM_STATE_WAITCONNECT);
1521 /* failure detected */
1522 stream_error = TRUE;
1528 #ifndef CURL_DISABLE_HTTP
1529 case CURLM_STATE_WAITPROXYCONNECT:
1530 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
1531 result = Curl_http_connect(data->easy_conn, &protocol_connect);
1533 if(data->easy_conn->bits.proxy_connect_closed) {
1534 rc = CURLM_CALL_MULTI_PERFORM;
1535 /* connect back to proxy again */
1537 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1538 multistate(data, CURLM_STATE_CONNECT);
1541 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE) {
1542 rc = CURLM_CALL_MULTI_PERFORM;
1543 /* initiate protocol connect phase */
1544 multistate(data, CURLM_STATE_SENDPROTOCONNECT);
1550 case CURLM_STATE_WAITCONNECT:
1551 /* awaiting a completion of an asynch TCP connect */
1552 result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
1553 if(connected && !result) {
1554 rc = CURLM_CALL_MULTI_PERFORM;
1555 multistate(data, data->easy_conn->bits.tunnel_proxy?
1556 CURLM_STATE_WAITPROXYCONNECT:
1557 CURLM_STATE_SENDPROTOCONNECT);
1560 /* failure detected */
1561 /* Just break, the cleaning up is handled all in one place */
1562 stream_error = TRUE;
1567 case CURLM_STATE_SENDPROTOCONNECT:
1568 result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
1569 if(!protocol_connect)
1570 /* switch to waiting state */
1571 multistate(data, CURLM_STATE_PROTOCONNECT);
1573 /* protocol connect has completed, go WAITDO or DO */
1574 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1575 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1576 rc = CURLM_CALL_MULTI_PERFORM;
1579 /* failure detected */
1580 Curl_posttransfer(data);
1581 multi_done(&data->easy_conn, result, TRUE);
1582 stream_error = TRUE;
1586 case CURLM_STATE_PROTOCONNECT:
1587 /* protocol-specific connect phase */
1588 result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
1589 if(!result && protocol_connect) {
1590 /* after the connect has completed, go WAITDO or DO */
1591 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1592 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1593 rc = CURLM_CALL_MULTI_PERFORM;
1596 /* failure detected */
1597 Curl_posttransfer(data);
1598 multi_done(&data->easy_conn, result, TRUE);
1599 stream_error = TRUE;
1603 case CURLM_STATE_WAITDO:
1604 /* Wait for our turn to DO when we're pipelining requests */
1605 if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
1606 /* Grabbed the channel */
1607 multistate(data, CURLM_STATE_DO);
1608 rc = CURLM_CALL_MULTI_PERFORM;
1612 case CURLM_STATE_DO:
1613 if(data->set.connect_only) {
1614 /* keep connection open for application to use the socket */
1615 connkeep(data->easy_conn, "CONNECT_ONLY");
1616 multistate(data, CURLM_STATE_DONE);
1618 rc = CURLM_CALL_MULTI_PERFORM;
1621 /* Perform the protocol's DO action */
1622 result = multi_do(&data->easy_conn, &dophase_done);
1624 /* When multi_do() returns failure, data->easy_conn might be NULL! */
1628 /* some steps needed for wildcard matching */
1629 if(data->set.wildcardmatch) {
1630 struct WildcardData *wc = &data->wildcard;
1631 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
1632 /* skip some states if it is important */
1633 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1634 multistate(data, CURLM_STATE_DONE);
1635 rc = CURLM_CALL_MULTI_PERFORM;
1639 /* DO was not completed in one function call, we must continue
1641 multistate(data, CURLM_STATE_DOING);
1645 /* after DO, go DO_DONE... or DO_MORE */
1646 else if(data->easy_conn->bits.do_more) {
1647 /* we're supposed to do more, but we need to sit down, relax
1648 and wait a little while first */
1649 multistate(data, CURLM_STATE_DO_MORE);
1653 /* we're done with the DO, now DO_DONE */
1654 multistate(data, CURLM_STATE_DO_DONE);
1655 rc = CURLM_CALL_MULTI_PERFORM;
1658 else if((CURLE_SEND_ERROR == result) &&
1659 data->easy_conn->bits.reuse) {
1661 * In this situation, a connection that we were trying to use
1662 * may have unexpectedly died. If possible, send the connection
1663 * back to the CONNECT phase so we can try again.
1665 char *newurl = NULL;
1666 followtype follow=FOLLOW_NONE;
1670 drc = Curl_retry_request(data->easy_conn, &newurl);
1672 /* a failure here pretty much implies an out of memory */
1674 stream_error = TRUE;
1677 retry = (newurl)?TRUE:FALSE;
1679 Curl_posttransfer(data);
1680 drc = multi_done(&data->easy_conn, result, FALSE);
1682 /* When set to retry the connection, we must to go back to
1683 * the CONNECT state */
1685 if(!drc || (drc == CURLE_SEND_ERROR)) {
1686 follow = FOLLOW_RETRY;
1687 drc = Curl_follow(data, newurl, follow);
1689 multistate(data, CURLM_STATE_CONNECT);
1690 rc = CURLM_CALL_MULTI_PERFORM;
1700 /* done didn't return OK or SEND_ERROR */
1706 /* Have error handler disconnect conn if we can't retry */
1707 stream_error = TRUE;
1712 /* failure detected */
1713 Curl_posttransfer(data);
1715 multi_done(&data->easy_conn, result, FALSE);
1716 stream_error = TRUE;
1721 case CURLM_STATE_DOING:
1722 /* we continue DOING until the DO phase is complete */
1723 result = Curl_protocol_doing(data->easy_conn,
1727 /* after DO, go DO_DONE or DO_MORE */
1728 multistate(data, data->easy_conn->bits.do_more?
1729 CURLM_STATE_DO_MORE:
1730 CURLM_STATE_DO_DONE);
1731 rc = CURLM_CALL_MULTI_PERFORM;
1732 } /* dophase_done */
1735 /* failure detected */
1736 Curl_posttransfer(data);
1737 multi_done(&data->easy_conn, result, FALSE);
1738 stream_error = TRUE;
1742 case CURLM_STATE_DO_MORE:
1744 * When we are connected, DO MORE and then go DO_DONE
1746 result = multi_do_more(data->easy_conn, &control);
1748 /* No need to remove this handle from the send pipeline here since that
1749 is done in multi_done() */
1752 /* if positive, advance to DO_DONE
1753 if negative, go back to DOING */
1754 multistate(data, control==1?
1755 CURLM_STATE_DO_DONE:
1757 rc = CURLM_CALL_MULTI_PERFORM;
1760 /* stay in DO_MORE */
1764 /* failure detected */
1765 Curl_posttransfer(data);
1766 multi_done(&data->easy_conn, result, FALSE);
1767 stream_error = TRUE;
1771 case CURLM_STATE_DO_DONE:
1772 /* Move ourselves from the send to recv pipeline */
1773 Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
1774 /* Check if we can move pending requests to send pipe */
1775 Curl_multi_process_pending_handles(multi);
1777 /* Only perform the transfer if there's a good socket to work with.
1778 Having both BAD is a signal to skip immediately to DONE */
1779 if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
1780 (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
1781 multistate(data, CURLM_STATE_WAITPERFORM);
1783 multistate(data, CURLM_STATE_DONE);
1784 rc = CURLM_CALL_MULTI_PERFORM;
1787 case CURLM_STATE_WAITPERFORM:
1788 /* Wait for our turn to PERFORM */
1789 if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
1790 /* Grabbed the channel */
1791 multistate(data, CURLM_STATE_PERFORM);
1792 rc = CURLM_CALL_MULTI_PERFORM;
1796 case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1797 /* if both rates are within spec, resume transfer */
1798 if(Curl_pgrsUpdate(data->easy_conn))
1799 result = CURLE_ABORTED_BY_CALLBACK;
1801 result = Curl_speedcheck(data, now);
1803 if(( (data->set.max_send_speed == 0) ||
1804 (Curl_pgrsLimitWaitTime(data->progress.uploaded,
1805 data->progress.ul_limit_size,
1806 data->set.max_send_speed,
1807 data->progress.ul_limit_start,
1809 ( (data->set.max_recv_speed == 0) ||
1810 (Curl_pgrsLimitWaitTime(data->progress.downloaded,
1811 data->progress.dl_limit_size,
1812 data->set.max_recv_speed,
1813 data->progress.dl_limit_start,
1815 multistate(data, CURLM_STATE_PERFORM);
1818 case CURLM_STATE_PERFORM:
1820 char *newurl = NULL;
1822 bool comeback = FALSE;
1824 /* check if over send speed */
1825 if(data->set.max_send_speed > 0) {
1826 timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
1827 data->progress.ul_limit_size,
1828 data->set.max_send_speed,
1829 data->progress.ul_limit_start,
1831 if(timeout_ms > 0) {
1832 multistate(data, CURLM_STATE_TOOFAST);
1833 Curl_expire_latest(data, timeout_ms);
1838 /* check if over recv speed */
1839 if(data->set.max_recv_speed > 0) {
1840 timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
1841 data->progress.dl_limit_size,
1842 data->set.max_recv_speed,
1843 data->progress.dl_limit_start,
1845 if(timeout_ms > 0) {
1846 multistate(data, CURLM_STATE_TOOFAST);
1847 Curl_expire_latest(data, timeout_ms);
1852 /* read/write data if it is ready to do so */
1853 result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
1857 if(!(k->keepon & KEEP_RECV))
1858 /* We're done receiving */
1859 Curl_pipeline_leave_read(data->easy_conn);
1861 if(!(k->keepon & KEEP_SEND))
1862 /* We're done sending */
1863 Curl_pipeline_leave_write(data->easy_conn);
1865 if(done || (result == CURLE_RECV_ERROR)) {
1866 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
1867 * condition and the server closed the re-used connection exactly when
1868 * we wanted to use it, so figure out if that is indeed the case.
1870 CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
1872 retry = (newurl)?TRUE:FALSE;
1875 /* if we are to retry, set the result to OK and consider the
1884 * The transfer phase returned error, we mark the connection to get
1885 * closed to prevent being re-used. This is because we can't possibly
1886 * know if the connection is in a good shape or not now. Unless it is
1887 * a protocol which uses two "channels" like FTP, as then the error
1888 * happened in the data connection.
1891 if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
1892 result != CURLE_HTTP2_STREAM)
1893 streamclose(data->easy_conn, "Transfer returned error");
1895 Curl_posttransfer(data);
1896 multi_done(&data->easy_conn, result, TRUE);
1899 followtype follow=FOLLOW_NONE;
1901 /* call this even if the readwrite function returned error */
1902 Curl_posttransfer(data);
1904 /* we're no longer receiving */
1905 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
1907 /* expire the new receiving pipeline head */
1908 if(data->easy_conn->recv_pipe->head)
1909 Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
1911 /* Check if we can move pending requests to send pipe */
1912 Curl_multi_process_pending_handles(multi);
1914 /* When we follow redirects or is set to retry the connection, we must
1915 to go back to the CONNECT state */
1916 if(data->req.newurl || retry) {
1918 /* if the URL is a follow-location and not just a retried request
1919 then figure out the URL here */
1921 newurl = data->req.newurl;
1922 data->req.newurl = NULL;
1923 follow = FOLLOW_REDIR;
1926 follow = FOLLOW_RETRY;
1927 result = multi_done(&data->easy_conn, CURLE_OK, FALSE);
1929 result = Curl_follow(data, newurl, follow);
1931 multistate(data, CURLM_STATE_CONNECT);
1932 rc = CURLM_CALL_MULTI_PERFORM;
1933 newurl = NULL; /* handed over the memory ownership to
1934 Curl_follow(), make sure we don't free() it
1940 /* after the transfer is done, go DONE */
1942 /* but first check to see if we got a location info even though we're
1943 not following redirects */
1944 if(data->req.location) {
1946 newurl = data->req.location;
1947 data->req.location = NULL;
1948 result = Curl_follow(data, newurl, FOLLOW_FAKE);
1950 newurl = NULL; /* allocation was handed over Curl_follow() */
1952 stream_error = TRUE;
1955 multistate(data, CURLM_STATE_DONE);
1956 rc = CURLM_CALL_MULTI_PERFORM;
1960 rc = CURLM_CALL_MULTI_PERFORM;
1966 case CURLM_STATE_DONE:
1967 /* this state is highly transient, so run another loop after this */
1968 rc = CURLM_CALL_MULTI_PERFORM;
1970 if(data->easy_conn) {
1973 /* Remove ourselves from the receive pipeline, if we are there. */
1974 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
1975 /* Check if we can move pending requests to send pipe */
1976 Curl_multi_process_pending_handles(multi);
1978 /* post-transfer command */
1979 res = multi_done(&data->easy_conn, result, FALSE);
1981 /* allow a previously set error code take precedence */
1986 * If there are other handles on the pipeline, multi_done won't set
1987 * easy_conn to NULL. In such a case, curl_multi_remove_handle() can
1988 * access free'd data, if the connection is free'd and the handle
1989 * removed before we perform the processing in CURLM_STATE_COMPLETED
1992 data->easy_conn = NULL;
1995 if(data->set.wildcardmatch) {
1996 if(data->wildcard.state != CURLWC_DONE) {
1997 /* if a wildcard is set and we are not ending -> lets start again
1998 with CURLM_STATE_INIT */
1999 multistate(data, CURLM_STATE_INIT);
2004 /* after we have DONE what we're supposed to do, go COMPLETED, and
2005 it doesn't matter what the multi_done() returned! */
2006 multistate(data, CURLM_STATE_COMPLETED);
2009 case CURLM_STATE_COMPLETED:
2010 /* this is a completed transfer, it is likely to still be connected */
2012 /* This node should be delinked from the list now and we should post
2013 an information message that we are complete. */
2015 /* Important: reset the conn pointer so that we don't point to memory
2016 that could be freed anytime */
2017 data->easy_conn = NULL;
2019 Curl_expire_clear(data); /* stop all timers */
2022 case CURLM_STATE_MSGSENT:
2023 data->result = result;
2024 return CURLM_OK; /* do nothing */
2027 return CURLM_INTERNAL_ERROR;
2031 if(data->mstate < CURLM_STATE_COMPLETED) {
2034 * If an error was returned, and we aren't in completed state now,
2035 * then we go to completed and consider this transfer aborted.
2038 /* NOTE: no attempt to disconnect connections must be made
2039 in the case blocks above - cleanup happens only here */
2041 data->state.pipe_broke = FALSE;
2043 /* Check if we can move pending requests to send pipe */
2044 Curl_multi_process_pending_handles(multi);
2046 if(data->easy_conn) {
2047 /* if this has a connection, unsubscribe from the pipelines */
2048 Curl_pipeline_leave_write(data->easy_conn);
2049 Curl_pipeline_leave_read(data->easy_conn);
2050 Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
2051 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
2054 /* Don't attempt to send data over a connection that timed out */
2055 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2056 /* disconnect properly */
2057 Curl_disconnect(data->easy_conn, dead_connection);
2059 /* This is where we make sure that the easy_conn pointer is reset.
2060 We don't have to do this in every case block above where a
2061 failure is detected */
2062 data->easy_conn = NULL;
2065 else if(data->mstate == CURLM_STATE_CONNECT) {
2066 /* Curl_connect() failed */
2067 (void)Curl_posttransfer(data);
2070 multistate(data, CURLM_STATE_COMPLETED);
2072 /* if there's still a connection to use, call the progress function */
2073 else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
2074 /* aborted due to progress callback return code must close the
2076 result = CURLE_ABORTED_BY_CALLBACK;
2077 streamclose(data->easy_conn, "Aborted by callback");
2079 /* if not yet in DONE state, go there, otherwise COMPLETED */
2080 multistate(data, (data->mstate < CURLM_STATE_DONE)?
2081 CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
2082 rc = CURLM_CALL_MULTI_PERFORM;
2086 if(CURLM_STATE_COMPLETED == data->mstate) {
2087 /* now fill in the Curl_message with this info */
2090 msg->extmsg.msg = CURLMSG_DONE;
2091 msg->extmsg.easy_handle = data;
2092 msg->extmsg.data.result = result;
2094 rc = multi_addmsg(multi, msg);
2096 multistate(data, CURLM_STATE_MSGSENT);
2098 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2100 data->result = result;
2107 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
2109 struct Curl_easy *data;
2110 CURLMcode returncode=CURLM_OK;
2111 struct Curl_tree *t;
2112 struct timeval now = Curl_tvnow();
2114 if(!GOOD_MULTI_HANDLE(multi))
2115 return CURLM_BAD_HANDLE;
2120 SIGPIPE_VARIABLE(pipe_st);
2122 sigpipe_ignore(data, &pipe_st);
2123 result = multi_runsingle(multi, now, data);
2124 sigpipe_restore(&pipe_st);
2127 returncode = result;
2129 data = data->next; /* operate on next handle */
2133 * Simply remove all expired timers from the splay since handles are dealt
2134 * with unconditionally by this function and curl_multi_timeout() requires
2135 * that already passed/handled expire times are removed from the splay.
2137 * It is important that the 'now' value is set at the entry of this function
2138 * and not for the current time as it may have ticked a little while since
2139 * then and then we risk this loop to remove timers that actually have not
2143 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2145 /* the removed may have another timeout in queue */
2146 (void)add_next_timeout(now, multi, t->payload);
2150 *running_handles = multi->num_alive;
2152 if(CURLM_OK >= returncode)
2153 update_timer(multi);
2158 static void close_all_connections(struct Curl_multi *multi)
2160 struct connectdata *conn;
2162 conn = Curl_conncache_find_first_connection(&multi->conn_cache);
2164 SIGPIPE_VARIABLE(pipe_st);
2165 conn->data = multi->closure_handle;
2167 sigpipe_ignore(conn->data, &pipe_st);
2168 conn->data->easy_conn = NULL; /* clear the easy handle's connection
2170 /* This will remove the connection from the cache */
2171 (void)Curl_disconnect(conn, FALSE);
2172 sigpipe_restore(&pipe_st);
2174 conn = Curl_conncache_find_first_connection(&multi->conn_cache);
2178 CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
2180 struct Curl_easy *data;
2181 struct Curl_easy *nextdata;
2183 if(GOOD_MULTI_HANDLE(multi)) {
2184 bool restore_pipe = FALSE;
2185 SIGPIPE_VARIABLE(pipe_st);
2187 multi->type = 0; /* not good anymore */
2189 /* Close all the connections in the connection cache */
2190 close_all_connections(multi);
2192 if(multi->closure_handle) {
2193 sigpipe_ignore(multi->closure_handle, &pipe_st);
2194 restore_pipe = TRUE;
2196 multi->closure_handle->dns.hostcache = &multi->hostcache;
2197 Curl_hostcache_clean(multi->closure_handle,
2198 multi->closure_handle->dns.hostcache);
2200 Curl_close(multi->closure_handle);
2203 Curl_hash_destroy(&multi->sockhash);
2204 Curl_conncache_destroy(&multi->conn_cache);
2205 Curl_llist_destroy(multi->msglist, NULL);
2206 Curl_llist_destroy(multi->pending, NULL);
2208 /* remove all easy handles */
2209 data = multi->easyp;
2211 nextdata=data->next;
2212 if(data->dns.hostcachetype == HCACHE_MULTI) {
2213 /* clear out the usage of the shared DNS cache */
2214 Curl_hostcache_clean(data, data->dns.hostcache);
2215 data->dns.hostcache = NULL;
2216 data->dns.hostcachetype = HCACHE_NONE;
2219 /* Clear the pointer to the connection cache */
2220 data->state.conn_cache = NULL;
2221 data->multi = NULL; /* clear the association */
2226 Curl_hash_destroy(&multi->hostcache);
2228 /* Free the blacklists by setting them to NULL */
2229 Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
2230 Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
2234 sigpipe_restore(&pipe_st);
2239 return CURLM_BAD_HANDLE;
2243 * curl_multi_info_read()
2245 * This function is the primary way for a multi/multi_socket application to
2246 * figure out if a transfer has ended. We MUST make this function as fast as
2247 * possible as it will be polled frequently and we MUST NOT scan any lists in
2248 * here to figure out things. We must scale fine to thousands of handles and
2249 * beyond. The current design is fully O(1).
2252 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
2254 struct Curl_message *msg;
2256 *msgs_in_queue = 0; /* default to none */
2258 if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
2259 /* there is one or more messages in the list */
2260 struct curl_llist_element *e;
2262 /* extract the head of the list to return */
2263 e = multi->msglist->head;
2267 /* remove the extracted entry */
2268 Curl_llist_remove(multi->msglist, e, NULL);
2270 *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
2272 return &msg->extmsg;
2279 * singlesocket() checks what sockets we deal with and their "action state"
2280 * and if we have a different state in any of those sockets from last time we
2281 * call the callback accordingly.
2283 static void singlesocket(struct Curl_multi *multi,
2284 struct Curl_easy *data)
2286 curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
2288 struct Curl_sh_entry *entry;
2291 unsigned int curraction;
2293 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
2294 socks[i] = CURL_SOCKET_BAD;
2296 /* Fill in the 'current' struct with the state as it is now: what sockets to
2297 supervise and for what actions */
2298 curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
2300 /* We have 0 .. N sockets already and we get to know about the 0 .. M
2301 sockets we should have from now on. Detect the differences, remove no
2302 longer supervised ones and add new ones */
2304 /* walk over the sockets we got right now */
2305 for(i=0; (i< MAX_SOCKSPEREASYHANDLE) &&
2306 (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
2308 int action = CURL_POLL_NONE;
2312 /* get it from the hash */
2313 entry = sh_getentry(&multi->sockhash, s);
2315 if(curraction & GETSOCK_READSOCK(i))
2316 action |= CURL_POLL_IN;
2317 if(curraction & GETSOCK_WRITESOCK(i))
2318 action |= CURL_POLL_OUT;
2321 /* yeps, already present so check if it has the same action set */
2322 if(entry->action == action)
2323 /* same, continue */
2327 /* this is a socket we didn't have before, add it! */
2328 entry = sh_addentry(&multi->sockhash, s, data);
2334 /* we know (entry != NULL) at this point, see the logic above */
2335 if(multi->socket_cb)
2336 multi->socket_cb(data,
2339 multi->socket_userp,
2342 entry->action = action; /* store the current action state */
2345 num = i; /* number of sockets */
2347 /* when we've walked over all the sockets we should have right now, we must
2348 make sure to detect sockets that are removed */
2349 for(i=0; i< data->numsocks; i++) {
2351 s = data->sockets[i];
2352 for(j=0; j<num; j++) {
2354 /* this is still supervised */
2355 s = CURL_SOCKET_BAD;
2360 entry = sh_getentry(&multi->sockhash, s);
2362 /* this socket has been removed. Tell the app to remove it */
2363 bool remove_sock_from_hash = TRUE;
2365 /* check if the socket to be removed serves a connection which has
2366 other easy-s in a pipeline. In this case the socket should not be
2368 struct connectdata *easy_conn = data->easy_conn;
2370 if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
2371 /* the handle should not be removed from the pipe yet */
2372 remove_sock_from_hash = FALSE;
2374 /* Update the sockhash entry to instead point to the next in line
2375 for the recv_pipe, or the first (in case this particular easy
2377 if(entry->easy == data) {
2378 if(Curl_recvpipe_head(data, easy_conn))
2379 entry->easy = easy_conn->recv_pipe->head->next->ptr;
2381 entry->easy = easy_conn->recv_pipe->head->ptr;
2384 if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
2385 /* the handle should not be removed from the pipe yet */
2386 remove_sock_from_hash = FALSE;
2388 /* Update the sockhash entry to instead point to the next in line
2389 for the send_pipe, or the first (in case this particular easy
2391 if(entry->easy == data) {
2392 if(Curl_sendpipe_head(data, easy_conn))
2393 entry->easy = easy_conn->send_pipe->head->next->ptr;
2395 entry->easy = easy_conn->send_pipe->head->ptr;
2398 /* Don't worry about overwriting recv_pipe head with send_pipe_head,
2399 when action will be asked on the socket (see multi_socket()), the
2400 head of the correct pipe will be taken according to the
2404 if(remove_sock_from_hash) {
2405 /* in this case 'entry' is always non-NULL */
2406 if(multi->socket_cb)
2407 multi->socket_cb(data,
2410 multi->socket_userp,
2412 sh_delentry(&multi->sockhash, s);
2414 } /* if sockhash entry existed */
2415 } /* for loop over numsocks */
2417 memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
2418 data->numsocks = num;
2422 * Curl_multi_closed()
2424 * Used by the connect code to tell the multi_socket code that one of the
2425 * sockets we were using is about to be closed. This function will then
2426 * remove it from the sockethash for this handle to make the multi_socket API
2427 * behave properly, especially for the case when libcurl will create another
2428 * socket again and it gets the same file descriptor number.
2431 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
2433 struct Curl_multi *multi = conn->data->multi;
2435 /* this is set if this connection is part of a handle that is added to
2436 a multi handle, and only then this is necessary */
2437 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2440 if(multi->socket_cb)
2441 multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
2442 multi->socket_userp,
2445 /* now remove it from the socket hash */
2446 sh_delentry(&multi->sockhash, s);
2454 * add_next_timeout()
2456 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
2457 * when it has just been removed from the splay tree because the timeout has
2458 * expired. This function is then to advance in the list to pick the next
2459 * timeout to use (skip the already expired ones) and add this node back to
2460 * the splay tree again.
2462 * The splay tree only has each sessionhandle as a single node and the nearest
2463 * timeout is used to sort it on.
2465 static CURLMcode add_next_timeout(struct timeval now,
2466 struct Curl_multi *multi,
2467 struct Curl_easy *d)
2469 struct timeval *tv = &d->state.expiretime;
2470 struct curl_llist *list = d->state.timeoutlist;
2471 struct curl_llist_element *e;
2473 /* move over the timeout list for this specific handle and remove all
2474 timeouts that are now passed tense and store the next pending
2476 for(e = list->head; e;) {
2477 struct curl_llist_element *n = e->next;
2478 long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
2480 /* remove outdated entry */
2481 Curl_llist_remove(list, e, NULL);
2483 /* the list is sorted so get out on the first mismatch */
2489 /* clear the expire times within the handles that we remove from the
2495 /* copy the first entry to 'tv' */
2496 memcpy(tv, e->ptr, sizeof(*tv));
2498 /* remove first entry from list */
2499 Curl_llist_remove(list, e, NULL);
2501 /* insert this node again into the splay */
2502 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2503 &d->state.timenode);
2508 static CURLMcode multi_socket(struct Curl_multi *multi,
2512 int *running_handles)
2514 CURLMcode result = CURLM_OK;
2515 struct Curl_easy *data = NULL;
2516 struct Curl_tree *t;
2517 struct timeval now = Curl_tvnow();
2520 /* *perform() deals with running_handles on its own */
2521 result = curl_multi_perform(multi, running_handles);
2523 /* walk through each easy handle and do the socket state change magic
2525 if(result != CURLM_BAD_HANDLE) {
2528 singlesocket(multi, data);
2533 /* or should we fall-through and do the timer-based stuff? */
2536 else if(s != CURL_SOCKET_TIMEOUT) {
2538 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2541 /* Unmatched socket, we can't act on it but we ignore this fact. In
2542 real-world tests it has been proved that libevent can in fact give
2543 the application actions even though the socket was just previously
2544 asked to get removed, so thus we better survive stray socket actions
2545 and just move on. */
2548 SIGPIPE_VARIABLE(pipe_st);
2552 if(data->magic != CURLEASY_MAGIC_NUMBER)
2553 /* bad bad bad bad bad bad bad */
2554 return CURLM_INTERNAL_ERROR;
2556 /* If the pipeline is enabled, take the handle which is in the head of
2557 the pipeline. If we should write into the socket, take the send_pipe
2558 head. If we should read from the socket, take the recv_pipe head. */
2559 if(data->easy_conn) {
2560 if((ev_bitmask & CURL_POLL_OUT) &&
2561 data->easy_conn->send_pipe &&
2562 data->easy_conn->send_pipe->head)
2563 data = data->easy_conn->send_pipe->head->ptr;
2564 else if((ev_bitmask & CURL_POLL_IN) &&
2565 data->easy_conn->recv_pipe &&
2566 data->easy_conn->recv_pipe->head)
2567 data = data->easy_conn->recv_pipe->head->ptr;
2570 if(data->easy_conn &&
2571 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2572 /* set socket event bitmask if they're not locked */
2573 data->easy_conn->cselect_bits = ev_bitmask;
2575 sigpipe_ignore(data, &pipe_st);
2576 result = multi_runsingle(multi, now, data);
2577 sigpipe_restore(&pipe_st);
2579 if(data->easy_conn &&
2580 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2581 /* clear the bitmask only if not locked */
2582 data->easy_conn->cselect_bits = 0;
2584 if(CURLM_OK >= result)
2585 /* get the socket(s) and check if the state has been changed since
2587 singlesocket(multi, data);
2589 /* Now we fall-through and do the timer-based stuff, since we don't want
2590 to force the user to have to deal with timeouts as long as at least
2591 one connection in fact has traffic. */
2593 data = NULL; /* set data to NULL again to avoid calling
2594 multi_runsingle() in case there's no need to */
2595 now = Curl_tvnow(); /* get a newer time since the multi_runsingle() loop
2596 may have taken some time */
2600 /* Asked to run due to time-out. Clear the 'lastcall' variable to force
2601 update_timer() to trigger a callback to the app again even if the same
2602 timeout is still the one to run after this call. That handles the case
2603 when the application asks libcurl to run the timeout prematurely. */
2604 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
2608 * The loop following here will go on as long as there are expire-times left
2609 * to process in the splay and 'data' will be re-assigned for every expired
2610 * handle we deal with.
2613 /* the first loop lap 'data' can be NULL */
2615 SIGPIPE_VARIABLE(pipe_st);
2617 sigpipe_ignore(data, &pipe_st);
2618 result = multi_runsingle(multi, now, data);
2619 sigpipe_restore(&pipe_st);
2621 if(CURLM_OK >= result)
2622 /* get the socket(s) and check if the state has been changed since
2624 singlesocket(multi, data);
2627 /* Check if there's one (more) expired timer to deal with! This function
2628 extracts a matching node if there is one */
2630 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2632 data = t->payload; /* assign this for next loop */
2633 (void)add_next_timeout(now, multi, t->payload);
2638 *running_handles = multi->num_alive;
2642 #undef curl_multi_setopt
2643 CURLMcode curl_multi_setopt(struct Curl_multi *multi,
2644 CURLMoption option, ...)
2646 CURLMcode res = CURLM_OK;
2649 if(!GOOD_MULTI_HANDLE(multi))
2650 return CURLM_BAD_HANDLE;
2652 va_start(param, option);
2655 case CURLMOPT_SOCKETFUNCTION:
2656 multi->socket_cb = va_arg(param, curl_socket_callback);
2658 case CURLMOPT_SOCKETDATA:
2659 multi->socket_userp = va_arg(param, void *);
2661 case CURLMOPT_PUSHFUNCTION:
2662 multi->push_cb = va_arg(param, curl_push_callback);
2664 case CURLMOPT_PUSHDATA:
2665 multi->push_userp = va_arg(param, void *);
2667 case CURLMOPT_PIPELINING:
2668 multi->pipelining = va_arg(param, long);
2670 case CURLMOPT_TIMERFUNCTION:
2671 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
2673 case CURLMOPT_TIMERDATA:
2674 multi->timer_userp = va_arg(param, void *);
2676 case CURLMOPT_MAXCONNECTS:
2677 multi->maxconnects = va_arg(param, long);
2679 case CURLMOPT_MAX_HOST_CONNECTIONS:
2680 multi->max_host_connections = va_arg(param, long);
2682 case CURLMOPT_MAX_PIPELINE_LENGTH:
2683 multi->max_pipeline_length = va_arg(param, long);
2685 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
2686 multi->content_length_penalty_size = va_arg(param, long);
2688 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
2689 multi->chunk_length_penalty_size = va_arg(param, long);
2691 case CURLMOPT_PIPELINING_SITE_BL:
2692 res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
2693 &multi->pipelining_site_bl);
2695 case CURLMOPT_PIPELINING_SERVER_BL:
2696 res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
2697 &multi->pipelining_server_bl);
2699 case CURLMOPT_MAX_TOTAL_CONNECTIONS:
2700 multi->max_total_connections = va_arg(param, long);
2703 res = CURLM_UNKNOWN_OPTION;
2710 /* we define curl_multi_socket() in the public multi.h header */
2711 #undef curl_multi_socket
2713 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
2714 int *running_handles)
2716 CURLMcode result = multi_socket(multi, FALSE, s, 0, running_handles);
2717 if(CURLM_OK >= result)
2718 update_timer(multi);
2722 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
2723 int ev_bitmask, int *running_handles)
2725 CURLMcode result = multi_socket(multi, FALSE, s,
2726 ev_bitmask, running_handles);
2727 if(CURLM_OK >= result)
2728 update_timer(multi);
2732 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
2735 CURLMcode result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0,
2737 if(CURLM_OK >= result)
2738 update_timer(multi);
2742 static CURLMcode multi_timeout(struct Curl_multi *multi,
2745 static struct timeval tv_zero = {0, 0};
2747 if(multi->timetree) {
2748 /* we have a tree of expire times */
2749 struct timeval now = Curl_tvnow();
2751 /* splay the lowest to the bottom */
2752 multi->timetree = Curl_splay(tv_zero, multi->timetree);
2754 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
2755 /* some time left before expiration */
2756 *timeout_ms = curlx_tvdiff(multi->timetree->key, now);
2759 * Since we only provide millisecond resolution on the returned value
2760 * and the diff might be less than one millisecond here, we don't
2761 * return zero as that may cause short bursts of busyloops on fast
2762 * processors while the diff is still present but less than one
2763 * millisecond! instead we return 1 until the time is ripe.
2768 /* 0 means immediately */
2777 CURLMcode curl_multi_timeout(struct Curl_multi *multi,
2780 /* First, make some basic checks that the CURLM handle is a good handle */
2781 if(!GOOD_MULTI_HANDLE(multi))
2782 return CURLM_BAD_HANDLE;
2784 return multi_timeout(multi, timeout_ms);
2788 * Tell the application it should update its timers, if it subscribes to the
2789 * update timer callback.
2791 static int update_timer(struct Curl_multi *multi)
2795 if(!multi->timer_cb)
2797 if(multi_timeout(multi, &timeout_ms)) {
2800 if(timeout_ms < 0) {
2801 static const struct timeval none={0, 0};
2802 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
2803 multi->timer_lastcall = none;
2804 /* there's no timeout now but there was one previously, tell the app to
2806 return multi->timer_cb(multi, -1, multi->timer_userp);
2811 /* When multi_timeout() is done, multi->timetree points to the node with the
2812 * timeout we got the (relative) time-out time for. We can thus easily check
2813 * if this is the same (fixed) time as we got in a previous call and then
2814 * avoid calling the callback again. */
2815 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
2818 multi->timer_lastcall = multi->timetree->key;
2820 return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
2824 * multi_freetimeout()
2826 * Callback used by the llist system when a single timeout list entry is
2829 static void multi_freetimeout(void *user, void *entryptr)
2833 /* the entry was plain malloc()'ed */
2838 * multi_addtimeout()
2840 * Add a timestamp to the list of timeouts. Keep the list sorted so that head
2841 * of list is always the timeout nearest in time.
2845 multi_addtimeout(struct curl_llist *timeoutlist,
2846 struct timeval *stamp)
2848 struct curl_llist_element *e;
2849 struct timeval *timedup;
2850 struct curl_llist_element *prev = NULL;
2852 timedup = malloc(sizeof(*timedup));
2854 return CURLM_OUT_OF_MEMORY;
2856 /* copy the timestamp */
2857 memcpy(timedup, stamp, sizeof(*timedup));
2859 if(Curl_llist_count(timeoutlist)) {
2860 /* find the correct spot in the list */
2861 for(e = timeoutlist->head; e; e = e->next) {
2862 struct timeval *checktime = e->ptr;
2863 long diff = curlx_tvdiff(*checktime, *timedup);
2871 this is the first timeout on the list */
2873 if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
2875 return CURLM_OUT_OF_MEMORY;
2884 * given a number of milliseconds from now to use to set the 'act before
2885 * this'-time for the transfer, to be extracted by curl_multi_timeout()
2887 * The timeout will be added to a queue of timeouts if it defines a moment in
2888 * time that is later than the current head of queue.
2890 void Curl_expire(struct Curl_easy *data, long milli)
2892 struct Curl_multi *multi = data->multi;
2893 struct timeval *nowp = &data->state.expiretime;
2897 /* this is only interesting while there is still an associated multi struct
2903 set.tv_sec += milli/1000;
2904 set.tv_usec += (milli%1000)*1000;
2906 if(set.tv_usec >= 1000000) {
2908 set.tv_usec -= 1000000;
2911 if(nowp->tv_sec || nowp->tv_usec) {
2912 /* This means that the struct is added as a node in the splay tree.
2913 Compare if the new time is earlier, and only remove-old/add-new if it
2915 long diff = curlx_tvdiff(set, *nowp);
2917 /* the new expire time was later so just add it to the queue
2919 multi_addtimeout(data->state.timeoutlist, &set);
2923 /* the new time is newer than the presently set one, so add the current
2924 to the queue and update the head */
2925 multi_addtimeout(data->state.timeoutlist, nowp);
2927 /* Since this is an updated time, we must remove the previous entry from
2928 the splay tree first and then re-add the new value */
2929 rc = Curl_splayremovebyaddr(multi->timetree,
2930 &data->state.timenode,
2933 infof(data, "Internal error removing splay node = %d\n", rc);
2937 data->state.timenode.payload = data;
2938 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
2939 &data->state.timenode);
2943 * Curl_expire_latest()
2945 * This is like Curl_expire() but will only add a timeout node to the list of
2946 * timers if there is no timeout that will expire before the given time.
2948 * Use this function if the code logic risks calling this function many times
2949 * or if there's no particular conditional wait in the code for this specific
2950 * time-out period to expire.
2953 void Curl_expire_latest(struct Curl_easy *data, long milli)
2955 struct timeval *expire = &data->state.expiretime;
2960 set.tv_sec += milli / 1000;
2961 set.tv_usec += (milli % 1000) * 1000;
2963 if(set.tv_usec >= 1000000) {
2965 set.tv_usec -= 1000000;
2968 if(expire->tv_sec || expire->tv_usec) {
2969 /* This means that the struct is added as a node in the splay tree.
2970 Compare if the new time is earlier, and only remove-old/add-new if it
2972 long diff = curlx_tvdiff(set, *expire);
2974 /* the new expire time was later than the top time, so just skip this */
2978 /* Just add the timeout like normal */
2979 Curl_expire(data, milli);
2984 * Curl_expire_clear()
2986 * Clear ALL timeout values for this handle.
2988 void Curl_expire_clear(struct Curl_easy *data)
2990 struct Curl_multi *multi = data->multi;
2991 struct timeval *nowp = &data->state.expiretime;
2994 /* this is only interesting while there is still an associated multi struct
2999 if(nowp->tv_sec || nowp->tv_usec) {
3000 /* Since this is an cleared time, we must remove the previous entry from
3002 struct curl_llist *list = data->state.timeoutlist;
3004 rc = Curl_splayremovebyaddr(multi->timetree,
3005 &data->state.timenode,
3008 infof(data, "Internal error clearing splay node = %d\n", rc);
3010 /* flush the timeout list too */
3011 while(list->size > 0)
3012 Curl_llist_remove(list, list->tail, NULL);
3015 infof(data, "Expire cleared\n");
3025 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
3028 struct Curl_sh_entry *there = NULL;
3030 there = sh_getentry(&multi->sockhash, s);
3033 return CURLM_BAD_SOCKET;
3035 there->socketp = hashp;
3040 size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
3042 return multi ? multi->max_host_connections : 0;
3045 size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
3047 return multi ? multi->max_total_connections : 0;
3050 curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
3052 return multi ? multi->content_length_penalty_size : 0;
3055 curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
3057 return multi ? multi->chunk_length_penalty_size : 0;
3060 struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
3062 return multi->pipelining_site_bl;
3065 struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
3067 return multi->pipelining_server_bl;
3070 void Curl_multi_process_pending_handles(struct Curl_multi *multi)
3072 struct curl_llist_element *e = multi->pending->head;
3075 struct Curl_easy *data = e->ptr;
3076 struct curl_llist_element *next = e->next;
3078 if(data->mstate == CURLM_STATE_CONNECT_PEND) {
3079 multistate(data, CURLM_STATE_CONNECT);
3081 /* Remove this node from the list */
3082 Curl_llist_remove(multi->pending, e, NULL);
3084 /* Make sure that the handle will be processed soonish. */
3085 Curl_expire_latest(data, 0);
3088 e = next; /* operate on next handle */
3093 void Curl_multi_dump(struct Curl_multi *multi)
3095 struct Curl_easy *data;
3097 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
3098 multi->num_easy, multi->num_alive);
3099 for(data=multi->easyp; data; data = data->next) {
3100 if(data->mstate < CURLM_STATE_COMPLETED) {
3101 /* only display handles that are not completed */
3102 fprintf(stderr, "handle %p, state %s, %d sockets\n",
3104 statename[data->mstate], data->numsocks);
3105 for(i=0; i < data->numsocks; i++) {
3106 curl_socket_t s = data->sockets[i];
3107 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3109 fprintf(stderr, "%d ", (int)s);
3111 fprintf(stderr, "INTERNAL CONFUSION\n");
3114 fprintf(stderr, "[%s %s] ",
3115 entry->action&CURL_POLL_IN?"RECVING":"",
3116 entry->action&CURL_POLL_OUT?"SENDING":"");
3119 fprintf(stderr, "\n");