1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, 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 http://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 ***************************************************************************/
25 #include <curl/curl.h>
39 #include "speedcheck.h"
40 #include "conncache.h"
43 #define _MPRINTF_REPLACE /* use our functions only */
44 #include <curl/mprintf.h>
46 #include "curl_memory.h"
47 /* The last #include file should be: */
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
60 /* the 'CURLMsg' is the part that is visible to the external user */
61 struct CURLMsg extmsg;
64 /* NOTE: if you add a state here, add the name to the statename[] array as
68 CURLM_STATE_INIT, /* 0 - start in this state */
69 CURLM_STATE_CONNECT, /* 1 - resolve/connect has been sent off */
70 CURLM_STATE_WAITRESOLVE, /* 2 - awaiting the resolve to finalize */
71 CURLM_STATE_WAITCONNECT, /* 3 - awaiting the connect to finalize */
72 CURLM_STATE_WAITPROXYCONNECT, /* 4 - awaiting proxy CONNECT to finalize */
73 CURLM_STATE_PROTOCONNECT, /* 5 - completing the protocol-specific connect
75 CURLM_STATE_WAITDO, /* 6 - wait for our turn to send the request */
76 CURLM_STATE_DO, /* 7 - start send off the request (part 1) */
77 CURLM_STATE_DOING, /* 8 - sending off the request (part 1) */
78 CURLM_STATE_DO_MORE, /* 9 - send off the request (part 2) */
79 CURLM_STATE_DO_DONE, /* 10 - done sending off request */
80 CURLM_STATE_WAITPERFORM, /* 11 - wait for our turn to read the response */
81 CURLM_STATE_PERFORM, /* 12 - transfer data */
82 CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */
83 CURLM_STATE_DONE, /* 14 - post data transfer operation */
84 CURLM_STATE_COMPLETED, /* 15 - operation complete */
85 CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */
86 CURLM_STATE_LAST /* 17 - not a true state, never use this */
89 /* we support N sockets per easy handle. Set the corresponding bit to what
90 action we should wait for */
91 #define MAX_SOCKSPEREASYHANDLE 5
92 #define GETSOCK_READABLE (0x00ff)
93 #define GETSOCK_WRITABLE (0xff00)
95 struct Curl_one_easy {
96 /* first, two fields for the linked list of these */
97 struct Curl_one_easy *next;
98 struct Curl_one_easy *prev;
100 struct SessionHandle *easy_handle; /* the easy handle for this unit */
101 struct connectdata *easy_conn; /* the "unit's" connection */
103 CURLMstate state; /* the handle's state */
104 CURLcode result; /* previous result */
106 struct Curl_message msg; /* A single posted message. */
108 /* Array with the plain socket numbers this handle takes care of, in no
109 particular order. Note that all sockets are added to the sockhash, where
110 the state etc are also kept. This array is mostly used to detect when a
111 socket is to be removed from the hash. See singlesocket(). */
112 curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
116 #define CURL_MULTI_HANDLE 0x000bab1e
118 #define GOOD_MULTI_HANDLE(x) \
119 ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
120 #define GOOD_EASY_HANDLE(x) \
121 ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
123 /* This is the struct known as CURLM on the outside */
125 /* First a simple identifier to easier detect if a user mix up
126 this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
129 /* We have a doubly-linked circular list with easy handles */
130 struct Curl_one_easy easy;
132 int num_easy; /* amount of entries in the linked list above. */
133 int num_alive; /* amount of easy handles that are added but have not yet
134 reached COMPLETE state */
136 struct curl_llist *msglist; /* a list of messages from completed transfers */
138 /* callback function and user data pointer for the *socket() API */
139 curl_socket_callback socket_cb;
143 struct curl_hash *hostcache;
145 /* timetree points to the splay-tree of time nodes to figure out expire
146 times of all currently set timers */
147 struct Curl_tree *timetree;
149 /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
150 the pluralis form, there can be more than one easy handle waiting on the
151 same actual socket) */
152 struct curl_hash *sockhash;
154 /* Whether pipelining is enabled for this multi handle */
155 bool pipelining_enabled;
157 /* Shared connection cache (bundles)*/
158 struct conncache *conn_cache;
160 /* This handle will be used for closing the cached connections in
161 curl_multi_cleanup() */
162 struct SessionHandle *closure_handle;
164 long maxconnects; /* if >0, a fixed limit of the maximum number of entries
165 we're allowed to grow the connection cache to */
167 /* timer callback and user data pointer for the *socket() API */
168 curl_multi_timer_callback timer_cb;
170 struct timeval timer_lastcall; /* the fixed time for the timeout for the
174 static void singlesocket(struct Curl_multi *multi,
175 struct Curl_one_easy *easy);
176 static int update_timer(struct Curl_multi *multi);
178 static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
179 struct connectdata *conn);
180 static int checkPendPipeline(struct connectdata *conn);
181 static void moveHandleFromSendToRecvPipeline(struct SessionHandle *handle,
182 struct connectdata *conn);
183 static void moveHandleFromRecvToDonePipeline(struct SessionHandle *handle,
184 struct connectdata *conn);
185 static bool isHandleAtHead(struct SessionHandle *handle,
186 struct curl_llist *pipeline);
187 static CURLMcode add_next_timeout(struct timeval now,
188 struct Curl_multi *multi,
189 struct SessionHandle *d);
192 static const char * const statename[]={
213 static void multi_freetimeout(void *a, void *b);
215 /* always use this function to change state, to make debugging easier */
216 static void multistate(struct Curl_one_easy *easy, CURLMstate state)
219 long connection_id = -5000;
221 CURLMstate oldstate = easy->state;
223 if(oldstate == state)
224 /* don't bother when the new state is the same as the old state */
230 if(easy->easy_conn) {
231 if(easy->state > CURLM_STATE_CONNECT &&
232 easy->state < CURLM_STATE_COMPLETED)
233 connection_id = easy->easy_conn->connection_id;
235 infof(easy->easy_handle,
236 "STATE: %s => %s handle %p; (connection #%ld) \n",
237 statename[oldstate], statename[easy->state],
238 (char *)easy, connection_id);
241 if(state == CURLM_STATE_COMPLETED)
242 /* changing to COMPLETED means there's one less easy handle 'alive' */
243 easy->easy_handle->multi->num_alive--;
247 * We add one of these structs to the sockhash for a particular socket
250 struct Curl_sh_entry {
251 struct SessionHandle *easy;
253 int action; /* what action READ/WRITE this socket waits for */
254 curl_socket_t socket; /* mainly to ease debugging */
255 void *socketp; /* settable by users with curl_multi_assign() */
257 /* bits for 'action' having no bits means this socket is not expecting any
262 /* make sure this socket is present in the hash for this handle */
263 static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
265 struct SessionHandle *data)
267 struct Curl_sh_entry *there =
268 Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
269 struct Curl_sh_entry *check;
272 /* it is present, return fine */
275 /* not present, add it */
276 check = calloc(1, sizeof(struct Curl_sh_entry));
278 return NULL; /* major failure */
282 /* make/add new hash entry */
283 if(NULL == Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
285 return NULL; /* major failure */
288 return check; /* things are good in sockhash land */
292 /* delete the given socket + handle from the hash */
293 static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
295 struct Curl_sh_entry *there =
296 Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
299 /* this socket is in the hash */
300 /* We remove the hash entry. (This'll end up in a call to
302 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
307 * free a sockhash entry
309 static void sh_freeentry(void *freethis)
311 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
317 static size_t fd_key_compare(void*k1, size_t k1_len, void*k2, size_t k2_len)
319 (void) k1_len; (void) k2_len;
321 return (*((int* ) k1)) == (*((int* ) k2));
324 static size_t hash_fd(void* key, size_t key_length, size_t slots_num)
326 int fd = * ((int* ) key);
329 return (fd % (int)slots_num);
333 * sh_init() creates a new socket hash and returns the handle for it.
335 * Quote from README.multi_socket:
337 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
338 * is somewhat of a bottle neck. Its current implementation may be a bit too
339 * limiting. It simply has a fixed-size array, and on each entry in the array
340 * it has a linked list with entries. So the hash only checks which list to
341 * scan through. The code I had used so for used a list with merely 7 slots
342 * (as that is what the DNS hash uses) but with 7000 connections that would
343 * make an average of 1000 nodes in each list to run through. I upped that to
344 * 97 slots (I believe a prime is suitable) and noticed a significant speed
345 * increase. I need to reconsider the hash implementation or use a rather
346 * large default value like this. At 9000 connections I was still below 10us
350 static struct curl_hash *sh_init(void)
352 return Curl_hash_alloc(CURL_SOCKET_HASH_TABLE_SIZE, hash_fd, fd_key_compare,
359 * Called when a transfer is completed. Adds the given msg pointer to
360 * the list kept in the multi handle.
362 static CURLMcode multi_addmsg(struct Curl_multi *multi,
363 struct Curl_message *msg)
365 if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
366 return CURLM_OUT_OF_MEMORY;
374 * Callback used by the llist system when a single list entry is destroyed.
376 static void multi_freeamsg(void *a, void *b)
382 CURLM *curl_multi_init(void)
384 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
389 multi->type = CURL_MULTI_HANDLE;
391 multi->hostcache = Curl_mk_dnscache();
392 if(!multi->hostcache)
395 multi->sockhash = sh_init();
399 multi->conn_cache = Curl_conncache_init(CONNCACHE_MULTI);
400 if(!multi->conn_cache)
403 multi->msglist = Curl_llist_alloc(multi_freeamsg);
407 /* Let's make the doubly-linked list a circular list. This makes
408 the linked list code simpler and allows inserting at the end
409 with less work (we didn't keep a tail pointer before). */
410 multi->easy.next = &multi->easy;
411 multi->easy.prev = &multi->easy;
413 return (CURLM *) multi;
417 Curl_hash_destroy(multi->sockhash);
418 multi->sockhash = NULL;
419 Curl_hash_destroy(multi->hostcache);
420 multi->hostcache = NULL;
421 Curl_conncache_destroy(multi->conn_cache);
422 multi->conn_cache = NULL;
428 CURLMcode curl_multi_add_handle(CURLM *multi_handle,
431 struct curl_llist *timeoutlist;
432 struct Curl_one_easy *easy;
433 struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
434 struct SessionHandle *data = (struct SessionHandle *)easy_handle;
435 struct SessionHandle *new_closure = NULL;
437 /* First, make some basic checks that the CURLM handle is a good handle */
438 if(!GOOD_MULTI_HANDLE(multi))
439 return CURLM_BAD_HANDLE;
441 /* Verify that we got a somewhat good easy handle too */
442 if(!GOOD_EASY_HANDLE(easy_handle))
443 return CURLM_BAD_EASY_HANDLE;
445 /* Prevent users from adding same easy handle more than
446 once and prevent adding to more than one multi stack */
448 /* possibly we should create a new unique error code for this condition */
449 return CURLM_BAD_EASY_HANDLE;
451 /* Allocate and initialize timeout list for easy handle */
452 timeoutlist = Curl_llist_alloc(multi_freetimeout);
454 return CURLM_OUT_OF_MEMORY;
456 /* Allocate new node for the doubly-linked circular list of
457 Curl_one_easy structs that holds pointers to easy handles */
458 easy = calloc(1, sizeof(struct Curl_one_easy));
460 Curl_llist_destroy(timeoutlist, NULL);
461 return CURLM_OUT_OF_MEMORY;
464 /* In case multi handle has no closure_handle yet, allocate
465 a new easy handle to use when closing cached connections */
466 if(!multi->closure_handle) {
467 new_closure = (struct SessionHandle *)curl_easy_init();
470 Curl_llist_destroy(timeoutlist, NULL);
471 return CURLM_OUT_OF_MEMORY;
476 ** No failure allowed in this function beyond this point. And
477 ** no modification of easy nor multi handle allowed before this
478 ** except for potential multi's connection cache growing which
479 ** won't be undone in this function no matter what.
482 /* In case a new closure handle has been initialized above, it
483 is associated now with the multi handle which lacked one. */
485 multi->closure_handle = new_closure;
486 Curl_easy_addmulti(multi->closure_handle, multi_handle);
487 multi->closure_handle->state.conn_cache = multi->conn_cache;
490 /* Make easy handle use timeout list initialized above */
491 data->state.timeoutlist = timeoutlist;
494 /* set the easy handle */
495 easy->easy_handle = data;
496 multistate(easy, CURLM_STATE_INIT);
498 /* set the back pointer to one_easy to assist in removal */
499 easy->easy_handle->multi_pos = easy;
501 /* for multi interface connections, we share DNS cache automatically if the
502 easy handle's one is currently private. */
503 if(easy->easy_handle->dns.hostcache &&
504 (easy->easy_handle->dns.hostcachetype == HCACHE_PRIVATE)) {
505 Curl_hash_destroy(easy->easy_handle->dns.hostcache);
506 easy->easy_handle->dns.hostcache = NULL;
507 easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
510 if(!easy->easy_handle->dns.hostcache ||
511 (easy->easy_handle->dns.hostcachetype == HCACHE_NONE)) {
512 easy->easy_handle->dns.hostcache = multi->hostcache;
513 easy->easy_handle->dns.hostcachetype = HCACHE_MULTI;
516 /* On a multi stack the connection cache, owned by the multi handle,
517 is shared between all easy handles within the multi handle.
518 Therefore we free the private connection cache if there is one */
519 if(easy->easy_handle->state.conn_cache &&
520 easy->easy_handle->state.conn_cache->type == CONNCACHE_PRIVATE) {
521 Curl_conncache_destroy(easy->easy_handle->state.conn_cache);
524 /* Point now to this multi's connection cache */
525 easy->easy_handle->state.conn_cache = multi->conn_cache;
527 /* This adds the new entry at the 'end' of the doubly-linked circular
528 list of Curl_one_easy structs to try and maintain a FIFO queue so
529 the pipelined requests are in order. */
531 /* We add this new entry last in the list. We make our 'next' point to the
532 'first' struct and our 'prev' point to the previous 'prev' */
533 easy->next = &multi->easy;
534 easy->prev = multi->easy.prev;
536 /* make 'easy' the last node in the chain */
537 multi->easy.prev = easy;
539 /* if there was a prev node, make sure its 'next' pointer links to
541 easy->prev->next = easy;
543 /* make the SessionHandle refer back to this multi handle */
544 Curl_easy_addmulti(easy_handle, multi_handle);
546 /* make the SessionHandle struct refer back to this struct */
547 easy->easy_handle->set.one_easy = easy;
549 /* Set the timeout for this handle to expire really soon so that it will
550 be taken care of even when this handle is added in the midst of operation
551 when only the curl_multi_socket() API is used. During that flow, only
552 sockets that time-out or have actions will be dealt with. Since this
553 handle has no action yet, we make sure it times out to get things to
555 Curl_expire(easy->easy_handle, 1);
557 /* increase the node-counter */
560 /* increase the alive-counter */
563 /* A somewhat crude work-around for a little glitch in update_timer() that
564 happens if the lastcall time is set to the same time when the handle is
565 removed as when the next handle is added, as then the check in
566 update_timer() that prevents calling the application multiple times with
567 the same timer infor will not trigger and then the new handle's timeout
568 will not be notified to the app.
570 The work-around is thus simply to clear the 'lastcall' variable to force
571 update_timer() to always trigger a callback to the app when a new easy
573 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
580 /* Debug-function, used like this:
582 * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
584 * Enable the hash print function first by editing hash.c
586 static void debug_print_sock_hash(void *p)
588 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
590 fprintf(stderr, " [easy %p/magic %x/socket %d]",
591 (void *)sh->easy, sh->easy->magic, (int)sh->socket);
595 CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
598 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
599 struct Curl_one_easy *easy;
600 struct SessionHandle *data = curl_handle;
602 /* First, make some basic checks that the CURLM handle is a good handle */
603 if(!GOOD_MULTI_HANDLE(multi))
604 return CURLM_BAD_HANDLE;
606 /* Verify that we got a somewhat good easy handle too */
607 if(!GOOD_EASY_HANDLE(curl_handle))
608 return CURLM_BAD_EASY_HANDLE;
610 /* pick-up from the 'curl_handle' the kept position in the list */
611 easy = data->multi_pos;
614 bool premature = (easy->state < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
615 bool easy_owns_conn = (easy->easy_conn &&
616 (easy->easy_conn->data == easy->easy_handle)) ?
619 /* If the 'state' is not INIT or COMPLETED, we might need to do something
620 nice to put the easy_handle in a good known state when this returns. */
622 /* this handle is "alive" so we need to count down the total number of
623 alive connections when this is removed */
626 if(easy->easy_conn &&
627 (easy->easy_conn->send_pipe->size +
628 easy->easy_conn->recv_pipe->size > 1) &&
629 easy->state > CURLM_STATE_WAITDO &&
630 easy->state < CURLM_STATE_COMPLETED) {
631 /* If the handle is in a pipeline and has started sending off its
632 request but not received its response yet, we need to close
634 easy->easy_conn->bits.close = TRUE;
635 /* Set connection owner so that Curl_done() closes it.
636 We can sefely do this here since connection is killed. */
637 easy->easy_conn->data = easy->easy_handle;
640 /* The timer must be shut down before easy->multi is set to NULL,
641 else the timenode will remain in the splay tree after
642 curl_easy_cleanup is called. */
643 Curl_expire(easy->easy_handle, 0);
645 /* destroy the timeout list that is held in the easy handle */
646 if(data->state.timeoutlist) {
647 Curl_llist_destroy(data->state.timeoutlist, NULL);
648 data->state.timeoutlist = NULL;
651 if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
652 /* clear out the usage of the shared DNS cache */
653 easy->easy_handle->dns.hostcache = NULL;
654 easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
657 if(easy->easy_conn) {
659 /* we must call Curl_done() here (if we still "own it") so that we don't
660 leave a half-baked one around */
663 /* Curl_done() clears the conn->data field to lose the association
664 between the easy handle and the connection
666 Note that this ignores the return code simply because there's
667 nothing really useful to do with it anyway! */
668 (void)Curl_done(&easy->easy_conn, easy->result, premature);
671 /* Clear connection pipelines, if Curl_done above was not called */
672 Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
675 if(easy->easy_handle->state.conn_cache->type == CONNCACHE_MULTI) {
676 /* if this was using the shared connection cache we clear the pointer
677 to that since we're not part of that handle anymore */
678 easy->easy_handle->state.conn_cache = NULL;
679 easy->easy_handle->state.lastconnect = NULL;
682 /* change state without using multistate(), only to make singlesocket() do
684 easy->state = CURLM_STATE_COMPLETED;
685 singlesocket(multi, easy); /* to let the application know what sockets
686 that vanish with this handle */
688 /* Remove the association between the connection and the handle */
689 if(easy->easy_conn) {
690 easy->easy_conn->data = NULL;
691 easy->easy_conn = NULL;
694 Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association
695 to this multi handle */
698 /* make sure there's no pending message in the queue sent from this easy
700 struct curl_llist_element *e;
702 for(e = multi->msglist->head; e; e = e->next) {
703 struct Curl_message *msg = e->ptr;
705 if(msg->extmsg.easy_handle == easy->easy_handle) {
706 Curl_llist_remove(multi->msglist, e, NULL);
707 /* there can only be one from this specific handle */
713 /* make the previous node point to our next */
715 easy->prev->next = easy->next;
716 /* make our next point to our previous node */
718 easy->next->prev = easy->prev;
720 easy->easy_handle->set.one_easy = NULL; /* detached */
722 /* Null the position in the controlling structure */
723 easy->easy_handle->multi_pos = NULL;
726 We do not touch the easy handle here! */
729 multi->num_easy--; /* one less to care about now */
735 return CURLM_BAD_EASY_HANDLE; /* twasn't found */
738 bool Curl_multi_canPipeline(const struct Curl_multi* multi)
740 return multi->pipelining_enabled;
743 void Curl_multi_handlePipeBreak(struct SessionHandle *data)
745 struct Curl_one_easy *one_easy = data->set.one_easy;
748 one_easy->easy_conn = NULL;
751 static int waitconnect_getsock(struct connectdata *conn,
756 return GETSOCK_BLANK;
758 sock[0] = conn->sock[FIRSTSOCKET];
760 /* when we've sent a CONNECT to a proxy, we should rather wait for the
761 socket to become readable to be able to get the response headers */
762 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
763 return GETSOCK_READSOCK(0);
765 return GETSOCK_WRITESOCK(0);
768 static int domore_getsock(struct connectdata *conn,
769 curl_socket_t *socks,
772 if(conn && conn->handler->domore_getsock)
773 return conn->handler->domore_getsock(conn, socks, numsocks);
774 return GETSOCK_BLANK;
777 /* returns bitmapped flags for this handle and its sockets */
778 static int multi_getsock(struct Curl_one_easy *easy,
779 curl_socket_t *socks, /* points to numsocks number
783 /* If the pipe broke, or if there's no connection left for this easy handle,
784 then we MUST bail out now with no bitmask set. The no connection case can
785 happen when this is called from curl_multi_remove_handle() =>
786 singlesocket() => multi_getsock().
788 if(easy->easy_handle->state.pipe_broke || !easy->easy_conn)
791 if(easy->state > CURLM_STATE_CONNECT &&
792 easy->state < CURLM_STATE_COMPLETED) {
793 /* Set up ownership correctly */
794 easy->easy_conn->data = easy->easy_handle;
797 switch(easy->state) {
799 #if 0 /* switch back on these cases to get the compiler to check for all enums
801 case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
802 case CURLM_STATE_COMPLETED:
803 case CURLM_STATE_MSGSENT:
804 case CURLM_STATE_INIT:
805 case CURLM_STATE_CONNECT:
806 case CURLM_STATE_WAITDO:
807 case CURLM_STATE_DONE:
808 case CURLM_STATE_LAST:
809 /* this will get called with CURLM_STATE_COMPLETED when a handle is
814 case CURLM_STATE_WAITRESOLVE:
815 return Curl_resolver_getsock(easy->easy_conn, socks, numsocks);
817 case CURLM_STATE_PROTOCONNECT:
818 return Curl_protocol_getsock(easy->easy_conn, socks, numsocks);
821 case CURLM_STATE_DOING:
822 return Curl_doing_getsock(easy->easy_conn, socks, numsocks);
824 case CURLM_STATE_WAITPROXYCONNECT:
825 case CURLM_STATE_WAITCONNECT:
826 return waitconnect_getsock(easy->easy_conn, socks, numsocks);
828 case CURLM_STATE_DO_MORE:
829 return domore_getsock(easy->easy_conn, socks, numsocks);
831 case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
832 to waiting for the same as the *PERFORM
834 case CURLM_STATE_PERFORM:
835 case CURLM_STATE_WAITPERFORM:
836 return Curl_single_getsock(easy->easy_conn, socks, numsocks);
841 CURLMcode curl_multi_fdset(CURLM *multi_handle,
842 fd_set *read_fd_set, fd_set *write_fd_set,
843 fd_set *exc_fd_set, int *max_fd)
845 /* Scan through all the easy handles to get the file descriptors set.
846 Some easy handles may not have connected to the remote host yet,
847 and then we must make sure that is done. */
848 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
849 struct Curl_one_easy *easy;
851 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
854 (void)exc_fd_set; /* not used */
856 if(!GOOD_MULTI_HANDLE(multi))
857 return CURLM_BAD_HANDLE;
859 easy=multi->easy.next;
860 while(easy != &multi->easy) {
861 bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
863 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
864 curl_socket_t s = CURL_SOCKET_BAD;
866 if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
867 FD_SET(sockbunch[i], read_fd_set);
870 if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
871 FD_SET(sockbunch[i], write_fd_set);
874 if(s == CURL_SOCKET_BAD)
875 /* this socket is unused, break out of loop */
878 if((int)s > this_max_fd)
879 this_max_fd = (int)s;
883 easy = easy->next; /* check next handle */
886 *max_fd = this_max_fd;
891 CURLMcode curl_multi_wait(CURLM *multi_handle,
892 struct curl_waitfd extra_fds[],
893 unsigned int extra_nfds,
897 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
898 struct Curl_one_easy *easy;
899 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
902 unsigned int nfds = extra_nfds;
905 if(!GOOD_MULTI_HANDLE(multi))
906 return CURLM_BAD_HANDLE;
908 /* Count up how many fds we have from the multi handle */
909 easy=multi->easy.next;
910 while(easy != &multi->easy) {
911 bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
913 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
914 curl_socket_t s = CURL_SOCKET_BAD;
916 if(bitmap & GETSOCK_READSOCK(i)) {
920 if(bitmap & GETSOCK_WRITESOCK(i)) {
924 if(s == CURL_SOCKET_BAD) {
929 easy = easy->next; /* check next handle */
932 ufds = (struct pollfd *)malloc(nfds * sizeof(struct pollfd));
935 /* Add the curl handles to our pollfds first */
936 easy=multi->easy.next;
937 while(easy != &multi->easy) {
938 bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
940 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
941 curl_socket_t s = CURL_SOCKET_BAD;
943 if(bitmap & GETSOCK_READSOCK(i)) {
944 ufds[nfds].fd = sockbunch[i];
945 ufds[nfds].events = POLLIN;
949 if(bitmap & GETSOCK_WRITESOCK(i)) {
950 ufds[nfds].fd = sockbunch[i];
951 ufds[nfds].events = POLLOUT;
955 if(s == CURL_SOCKET_BAD) {
960 easy = easy->next; /* check next handle */
963 /* Add external file descriptions from poll-like struct curl_waitfd */
964 for(i = 0; i < extra_nfds; i++) {
965 ufds[nfds].fd = extra_fds[i].fd;
966 ufds[nfds].events = 0;
967 if(extra_fds[i].events & CURL_WAIT_POLLIN)
968 ufds[nfds].events |= POLLIN;
969 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
970 ufds[nfds].events |= POLLPRI;
971 if(extra_fds[i].events & CURL_WAIT_POLLOUT)
972 ufds[nfds].events |= POLLOUT;
978 i = Curl_poll(ufds, nfds, timeout_ms);
988 static CURLMcode multi_runsingle(struct Curl_multi *multi,
990 struct Curl_one_easy *easy)
992 struct Curl_message *msg = NULL;
995 bool protocol_connect = FALSE;
998 CURLMcode result = CURLM_OK;
999 struct SingleRequest *k;
1000 struct SessionHandle *data;
1003 if(!GOOD_EASY_HANDLE(easy->easy_handle))
1004 return CURLM_BAD_EASY_HANDLE;
1006 data = easy->easy_handle;
1009 /* this is a single-iteration do-while loop just to allow a
1010 break to skip to the end of it */
1011 bool disconnect_conn = FALSE;
1013 /* Handle the case when the pipe breaks, i.e., the connection
1014 we're using gets cleaned up and we're left with nothing. */
1015 if(data->state.pipe_broke) {
1016 infof(data, "Pipe broke: handle 0x%p, url = %s\n",
1017 easy, data->state.path);
1019 if(easy->state < CURLM_STATE_COMPLETED) {
1020 /* Head back to the CONNECT state */
1021 multistate(easy, CURLM_STATE_CONNECT);
1022 result = CURLM_CALL_MULTI_PERFORM;
1023 easy->result = CURLE_OK;
1026 data->state.pipe_broke = FALSE;
1027 easy->easy_conn = NULL;
1031 if(!easy->easy_conn &&
1032 easy->state > CURLM_STATE_CONNECT &&
1033 easy->state < CURLM_STATE_DONE) {
1034 /* In all these states, the code will blindly access 'easy->easy_conn'
1035 so this is precaution that it isn't NULL. And it silences static
1037 failf(data, "In state %d with no easy_conn, bail out!\n", easy->state);
1038 return CURLM_INTERNAL_ERROR;
1041 if(easy->easy_conn && easy->state > CURLM_STATE_CONNECT &&
1042 easy->state < CURLM_STATE_COMPLETED)
1043 /* Make sure we set the connection's current owner */
1044 easy->easy_conn->data = data;
1046 if(easy->easy_conn &&
1047 (easy->state >= CURLM_STATE_CONNECT) &&
1048 (easy->state < CURLM_STATE_COMPLETED)) {
1049 /* we need to wait for the connect state as only then is the start time
1050 stored, but we must not check already completed handles */
1052 timeout_ms = Curl_timeleft(data, &now,
1053 (easy->state <= CURLM_STATE_WAITDO)?
1056 if(timeout_ms < 0) {
1057 /* Handle timed out */
1058 if(easy->state == CURLM_STATE_WAITRESOLVE)
1059 failf(data, "Resolving timed out after %ld milliseconds",
1060 Curl_tvdiff(now, data->progress.t_startsingle));
1061 else if(easy->state == CURLM_STATE_WAITCONNECT)
1062 failf(data, "Connection timed out after %ld milliseconds",
1063 Curl_tvdiff(now, data->progress.t_startsingle));
1066 failf(data, "Operation timed out after %ld milliseconds with %"
1067 FORMAT_OFF_T " out of %" FORMAT_OFF_T " bytes received",
1068 Curl_tvdiff(now, data->progress.t_startsingle), k->bytecount,
1072 /* Force the connection closed because the server could continue to
1073 send us stuff at any time. (The disconnect_conn logic used below
1074 doesn't work at this point). */
1075 easy->easy_conn->bits.close = TRUE;
1076 easy->result = CURLE_OPERATION_TIMEDOUT;
1077 multistate(easy, CURLM_STATE_COMPLETED);
1082 switch(easy->state) {
1083 case CURLM_STATE_INIT:
1084 /* init this transfer. */
1085 easy->result=Curl_pretransfer(data);
1087 if(CURLE_OK == easy->result) {
1088 /* after init, go CONNECT */
1089 multistate(easy, CURLM_STATE_CONNECT);
1090 result = CURLM_CALL_MULTI_PERFORM;
1092 data->state.used_interface = Curl_if_multi;
1096 case CURLM_STATE_CONNECT:
1097 /* Connect. We get a connection identifier filled in. */
1098 Curl_pgrsTime(data, TIMER_STARTSINGLE);
1099 easy->result = Curl_connect(data, &easy->easy_conn,
1100 &async, &protocol_connect);
1102 if(CURLE_OK == easy->result) {
1103 /* Add this handle to the send or pend pipeline */
1104 easy->result = addHandleToSendOrPendPipeline(data,
1106 if(CURLE_OK != easy->result)
1107 disconnect_conn = TRUE;
1110 /* We're now waiting for an asynchronous name lookup */
1111 multistate(easy, CURLM_STATE_WAITRESOLVE);
1113 /* after the connect has been sent off, go WAITCONNECT unless the
1114 protocol connect is already done and we can go directly to
1116 result = CURLM_CALL_MULTI_PERFORM;
1118 if(protocol_connect)
1119 multistate(easy, multi->pipelining_enabled?
1120 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1122 #ifndef CURL_DISABLE_HTTP
1123 if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1124 multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1127 multistate(easy, CURLM_STATE_WAITCONNECT);
1134 case CURLM_STATE_WAITRESOLVE:
1135 /* awaiting an asynch name resolve to complete */
1137 struct Curl_dns_entry *dns = NULL;
1139 /* check if we have the name resolved by now */
1140 easy->result = Curl_resolver_is_resolved(easy->easy_conn, &dns);
1142 /* Update sockets here, because the socket(s) may have been
1143 closed and the application thus needs to be told, even if it
1144 is likely that the same socket(s) will again be used further
1145 down. If the name has not yet been resolved, it is likely
1146 that new sockets have been opened in an attempt to contact
1147 another resolver. */
1148 singlesocket(multi, easy);
1151 /* Perform the next step in the connection phase, and then move on
1152 to the WAITCONNECT state */
1153 easy->result = Curl_async_resolved(easy->easy_conn,
1156 if(CURLE_OK != easy->result)
1157 /* if Curl_async_resolved() returns failure, the connection struct
1158 is already freed and gone */
1159 easy->easy_conn = NULL; /* no more connection */
1161 /* call again please so that we get the next socket setup */
1162 result = CURLM_CALL_MULTI_PERFORM;
1163 if(protocol_connect)
1164 multistate(easy, multi->pipelining_enabled?
1165 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1167 #ifndef CURL_DISABLE_HTTP
1168 if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1169 multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1172 multistate(easy, CURLM_STATE_WAITCONNECT);
1177 if(CURLE_OK != easy->result) {
1178 /* failure detected */
1179 disconnect_conn = TRUE;
1185 #ifndef CURL_DISABLE_HTTP
1186 case CURLM_STATE_WAITPROXYCONNECT:
1187 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
1188 easy->result = Curl_http_connect(easy->easy_conn, &protocol_connect);
1190 if(easy->easy_conn->bits.proxy_connect_closed) {
1191 /* reset the error buffer */
1192 if(data->set.errorbuffer)
1193 data->set.errorbuffer[0] = '\0';
1194 data->state.errorbuf = FALSE;
1196 easy->result = CURLE_OK;
1197 result = CURLM_CALL_MULTI_PERFORM;
1198 multistate(easy, CURLM_STATE_CONNECT);
1200 else if(CURLE_OK == easy->result) {
1201 if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
1202 multistate(easy, CURLM_STATE_WAITCONNECT);
1207 case CURLM_STATE_WAITCONNECT:
1208 /* awaiting a completion of an asynch connect */
1209 easy->result = Curl_is_connected(easy->easy_conn,
1215 /* if everything is still fine we do the protocol-specific connect
1217 easy->result = Curl_protocol_connect(easy->easy_conn,
1221 if(CURLE_OK != easy->result) {
1222 /* failure detected */
1223 /* Just break, the cleaning up is handled all in one place */
1224 disconnect_conn = TRUE;
1229 if(!protocol_connect) {
1230 /* We have a TCP connection, but 'protocol_connect' may be false
1231 and then we continue to 'STATE_PROTOCONNECT'. If protocol
1232 connect is TRUE, we move on to STATE_DO.
1233 BUT if we are using a proxy we must change to WAITPROXYCONNECT
1235 #ifndef CURL_DISABLE_HTTP
1236 if(easy->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1237 multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
1240 multistate(easy, CURLM_STATE_PROTOCONNECT);
1244 /* after the connect has completed, go WAITDO or DO */
1245 multistate(easy, multi->pipelining_enabled?
1246 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1248 result = CURLM_CALL_MULTI_PERFORM;
1252 case CURLM_STATE_PROTOCONNECT:
1253 /* protocol-specific connect phase */
1254 easy->result = Curl_protocol_connecting(easy->easy_conn,
1256 if((easy->result == CURLE_OK) && protocol_connect) {
1257 /* after the connect has completed, go WAITDO or DO */
1258 multistate(easy, multi->pipelining_enabled?
1259 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1260 result = CURLM_CALL_MULTI_PERFORM;
1262 else if(easy->result) {
1263 /* failure detected */
1264 Curl_posttransfer(data);
1265 Curl_done(&easy->easy_conn, easy->result, TRUE);
1266 disconnect_conn = TRUE;
1270 case CURLM_STATE_WAITDO:
1271 /* Wait for our turn to DO when we're pipelining requests */
1273 infof(data, "WAITDO: Conn %ld send pipe %zu inuse %d athead %d\n",
1274 easy->easy_conn->connection_id,
1275 easy->easy_conn->send_pipe->size,
1276 easy->easy_conn->writechannel_inuse?1:0,
1277 isHandleAtHead(data,
1278 easy->easy_conn->send_pipe)?1:0);
1280 if(!easy->easy_conn->writechannel_inuse &&
1281 isHandleAtHead(data,
1282 easy->easy_conn->send_pipe)) {
1283 /* Grab the channel */
1284 easy->easy_conn->writechannel_inuse = TRUE;
1285 multistate(easy, CURLM_STATE_DO);
1286 result = CURLM_CALL_MULTI_PERFORM;
1290 case CURLM_STATE_DO:
1291 if(data->set.connect_only) {
1292 /* keep connection open for application to use the socket */
1293 easy->easy_conn->bits.close = FALSE;
1294 multistate(easy, CURLM_STATE_DONE);
1295 easy->result = CURLE_OK;
1296 result = CURLM_CALL_MULTI_PERFORM;
1299 /* Perform the protocol's DO action */
1300 easy->result = Curl_do(&easy->easy_conn,
1303 if(CURLE_OK == easy->result) {
1305 /* some steps needed for wildcard matching */
1306 if(data->set.wildcardmatch) {
1307 struct WildcardData *wc = &data->wildcard;
1308 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
1309 /* skip some states if it is important */
1310 Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
1311 multistate(easy, CURLM_STATE_DONE);
1312 result = CURLM_CALL_MULTI_PERFORM;
1316 /* DO was not completed in one function call, we must continue
1318 multistate(easy, CURLM_STATE_DOING);
1322 /* after DO, go DO_DONE... or DO_MORE */
1323 else if(easy->easy_conn->bits.do_more) {
1324 /* we're supposed to do more, but we need to sit down, relax
1325 and wait a little while first */
1326 multistate(easy, CURLM_STATE_DO_MORE);
1330 /* we're done with the DO, now DO_DONE */
1331 multistate(easy, CURLM_STATE_DO_DONE);
1332 result = CURLM_CALL_MULTI_PERFORM;
1335 else if((CURLE_SEND_ERROR == easy->result) &&
1336 easy->easy_conn->bits.reuse) {
1338 * In this situation, a connection that we were trying to use
1339 * may have unexpectedly died. If possible, send the connection
1340 * back to the CONNECT phase so we can try again.
1342 char *newurl = NULL;
1343 followtype follow=FOLLOW_NONE;
1347 drc = Curl_retry_request(easy->easy_conn, &newurl);
1349 /* a failure here pretty much implies an out of memory */
1351 disconnect_conn = TRUE;
1354 retry = (newurl)?TRUE:FALSE;
1356 Curl_posttransfer(data);
1357 drc = Curl_done(&easy->easy_conn, easy->result, FALSE);
1359 /* When set to retry the connection, we must to go back to
1360 * the CONNECT state */
1362 if((drc == CURLE_OK) || (drc == CURLE_SEND_ERROR)) {
1363 follow = FOLLOW_RETRY;
1364 drc = Curl_follow(data, newurl, follow);
1365 if(drc == CURLE_OK) {
1366 multistate(easy, CURLM_STATE_CONNECT);
1367 result = CURLM_CALL_MULTI_PERFORM;
1368 easy->result = CURLE_OK;
1377 /* done didn't return OK or SEND_ERROR */
1383 /* Have error handler disconnect conn if we can't retry */
1384 disconnect_conn = TRUE;
1388 /* failure detected */
1389 Curl_posttransfer(data);
1390 Curl_done(&easy->easy_conn, easy->result, FALSE);
1391 disconnect_conn = TRUE;
1396 case CURLM_STATE_DOING:
1397 /* we continue DOING until the DO phase is complete */
1398 easy->result = Curl_protocol_doing(easy->easy_conn,
1400 if(CURLE_OK == easy->result) {
1402 /* after DO, go DO_DONE or DO_MORE */
1403 multistate(easy, easy->easy_conn->bits.do_more?
1404 CURLM_STATE_DO_MORE:
1405 CURLM_STATE_DO_DONE);
1406 result = CURLM_CALL_MULTI_PERFORM;
1407 } /* dophase_done */
1410 /* failure detected */
1411 Curl_posttransfer(data);
1412 Curl_done(&easy->easy_conn, easy->result, FALSE);
1413 disconnect_conn = TRUE;
1417 case CURLM_STATE_DO_MORE:
1419 * When we are connected, DO MORE and then go DO_DONE
1421 easy->result = Curl_do_more(easy->easy_conn, &dophase_done);
1423 /* No need to remove this handle from the send pipeline here since that
1424 is done in Curl_done() */
1425 if(CURLE_OK == easy->result) {
1427 multistate(easy, CURLM_STATE_DO_DONE);
1428 result = CURLM_CALL_MULTI_PERFORM;
1431 /* stay in DO_MORE */
1435 /* failure detected */
1436 Curl_posttransfer(data);
1437 Curl_done(&easy->easy_conn, easy->result, FALSE);
1438 disconnect_conn = TRUE;
1442 case CURLM_STATE_DO_DONE:
1443 /* Move ourselves from the send to recv pipeline */
1444 moveHandleFromSendToRecvPipeline(data, easy->easy_conn);
1445 /* Check if we can move pending requests to send pipe */
1446 checkPendPipeline(easy->easy_conn);
1447 multistate(easy, CURLM_STATE_WAITPERFORM);
1448 result = CURLM_CALL_MULTI_PERFORM;
1451 case CURLM_STATE_WAITPERFORM:
1452 /* Wait for our turn to PERFORM */
1453 if(!easy->easy_conn->readchannel_inuse &&
1454 isHandleAtHead(data,
1455 easy->easy_conn->recv_pipe)) {
1456 /* Grab the channel */
1457 easy->easy_conn->readchannel_inuse = TRUE;
1458 multistate(easy, CURLM_STATE_PERFORM);
1459 result = CURLM_CALL_MULTI_PERFORM;
1463 infof(data, "WAITPERFORM: Conn %ld recv pipe %zu inuse %d athead %d\n",
1464 easy->easy_conn->connection_id,
1465 easy->easy_conn->recv_pipe->size,
1466 easy->easy_conn->readchannel_inuse?1:0,
1467 isHandleAtHead(data,
1468 easy->easy_conn->recv_pipe)?1:0);
1473 case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1474 /* if both rates are within spec, resume transfer */
1475 if(Curl_pgrsUpdate(easy->easy_conn))
1476 easy->result = CURLE_ABORTED_BY_CALLBACK;
1478 easy->result = Curl_speedcheck(data, now);
1480 if(( (data->set.max_send_speed == 0) ||
1481 (data->progress.ulspeed < data->set.max_send_speed )) &&
1482 ( (data->set.max_recv_speed == 0) ||
1483 (data->progress.dlspeed < data->set.max_recv_speed)))
1484 multistate(easy, CURLM_STATE_PERFORM);
1487 case CURLM_STATE_PERFORM:
1489 char *newurl = NULL;
1492 /* check if over send speed */
1493 if((data->set.max_send_speed > 0) &&
1494 (data->progress.ulspeed > data->set.max_send_speed)) {
1497 multistate(easy, CURLM_STATE_TOOFAST);
1499 /* calculate upload rate-limitation timeout. */
1500 buffersize = (int)(data->set.buffer_size ?
1501 data->set.buffer_size : BUFSIZE);
1502 timeout_ms = Curl_sleep_time(data->set.max_send_speed,
1503 data->progress.ulspeed, buffersize);
1504 Curl_expire(data, timeout_ms);
1508 /* check if over recv speed */
1509 if((data->set.max_recv_speed > 0) &&
1510 (data->progress.dlspeed > data->set.max_recv_speed)) {
1513 multistate(easy, CURLM_STATE_TOOFAST);
1515 /* Calculate download rate-limitation timeout. */
1516 buffersize = (int)(data->set.buffer_size ?
1517 data->set.buffer_size : BUFSIZE);
1518 timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
1519 data->progress.dlspeed, buffersize);
1520 Curl_expire(data, timeout_ms);
1524 /* read/write data if it is ready to do so */
1525 easy->result = Curl_readwrite(easy->easy_conn, &done);
1529 if(!(k->keepon & KEEP_RECV)) {
1530 /* We're done receiving */
1531 easy->easy_conn->readchannel_inuse = FALSE;
1534 if(!(k->keepon & KEEP_SEND)) {
1535 /* We're done sending */
1536 easy->easy_conn->writechannel_inuse = FALSE;
1539 if(done || (easy->result == CURLE_RECV_ERROR)) {
1540 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
1541 * condition and the server closed the re-used connection exactly when
1542 * we wanted to use it, so figure out if that is indeed the case.
1544 CURLcode ret = Curl_retry_request(easy->easy_conn, &newurl);
1546 retry = (newurl)?TRUE:FALSE;
1549 /* if we are to retry, set the result to OK */
1550 easy->result = CURLE_OK;
1555 * The transfer phase returned error, we mark the connection to get
1556 * closed to prevent being re-used. This is because we can't possibly
1557 * know if the connection is in a good shape or not now. Unless it is
1558 * a protocol which uses two "channels" like FTP, as then the error
1559 * happened in the data connection.
1562 if(!(easy->easy_conn->handler->flags & PROTOPT_DUAL))
1563 easy->easy_conn->bits.close = TRUE;
1565 Curl_posttransfer(data);
1566 Curl_done(&easy->easy_conn, easy->result, FALSE);
1569 followtype follow=FOLLOW_NONE;
1571 /* call this even if the readwrite function returned error */
1572 Curl_posttransfer(data);
1574 /* we're no longer receiving */
1575 moveHandleFromRecvToDonePipeline(data,
1578 /* expire the new receiving pipeline head */
1579 if(easy->easy_conn->recv_pipe->head)
1580 Curl_expire(easy->easy_conn->recv_pipe->head->ptr, 1);
1582 /* Check if we can move pending requests to send pipe */
1583 checkPendPipeline(easy->easy_conn);
1585 /* When we follow redirects or is set to retry the connection, we must
1586 to go back to the CONNECT state */
1587 if(data->req.newurl || retry) {
1589 /* if the URL is a follow-location and not just a retried request
1590 then figure out the URL here */
1591 newurl = data->req.newurl;
1592 data->req.newurl = NULL;
1593 follow = FOLLOW_REDIR;
1596 follow = FOLLOW_RETRY;
1597 easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
1598 if(easy->result == CURLE_OK)
1599 easy->result = Curl_follow(data, newurl, follow);
1600 if(CURLE_OK == easy->result) {
1601 multistate(easy, CURLM_STATE_CONNECT);
1602 result = CURLM_CALL_MULTI_PERFORM;
1603 newurl = NULL; /* handed over the memory ownership to
1604 Curl_follow(), make sure we don't free() it
1609 /* after the transfer is done, go DONE */
1611 /* but first check to see if we got a location info even though we're
1612 not following redirects */
1613 if(data->req.location) {
1616 newurl = data->req.location;
1617 data->req.location = NULL;
1618 easy->result = Curl_follow(data, newurl, FOLLOW_FAKE);
1619 if(CURLE_OK == easy->result)
1620 newurl = NULL; /* allocation was handed over Curl_follow() */
1622 disconnect_conn = TRUE;
1625 multistate(easy, CURLM_STATE_DONE);
1626 result = CURLM_CALL_MULTI_PERFORM;
1635 case CURLM_STATE_DONE:
1637 if(easy->easy_conn) {
1638 /* Remove ourselves from the receive and done pipelines. Handle
1639 should be on one of these lists, depending upon how we got here. */
1640 Curl_removeHandleFromPipeline(data,
1641 easy->easy_conn->recv_pipe);
1642 Curl_removeHandleFromPipeline(data,
1643 easy->easy_conn->done_pipe);
1644 /* Check if we can move pending requests to send pipe */
1645 checkPendPipeline(easy->easy_conn);
1647 if(easy->easy_conn->bits.stream_was_rewound) {
1648 /* This request read past its response boundary so we quickly let
1649 the other requests consume those bytes since there is no
1650 guarantee that the socket will become active again */
1651 result = CURLM_CALL_MULTI_PERFORM;
1654 /* post-transfer command */
1655 easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
1657 * If there are other handles on the pipeline, Curl_done won't set
1658 * easy_conn to NULL. In such a case, curl_multi_remove_handle() can
1659 * access free'd data, if the connection is free'd and the handle
1660 * removed before we perform the processing in CURLM_STATE_COMPLETED
1663 easy->easy_conn = NULL;
1666 if(data->set.wildcardmatch) {
1667 if(data->wildcard.state != CURLWC_DONE) {
1668 /* if a wildcard is set and we are not ending -> lets start again
1669 with CURLM_STATE_INIT */
1670 result = CURLM_CALL_MULTI_PERFORM;
1671 multistate(easy, CURLM_STATE_INIT);
1676 /* after we have DONE what we're supposed to do, go COMPLETED, and
1677 it doesn't matter what the Curl_done() returned! */
1678 multistate(easy, CURLM_STATE_COMPLETED);
1682 case CURLM_STATE_COMPLETED:
1683 /* this is a completed transfer, it is likely to still be connected */
1685 /* This node should be delinked from the list now and we should post
1686 an information message that we are complete. */
1688 /* Important: reset the conn pointer so that we don't point to memory
1689 that could be freed anytime */
1690 easy->easy_conn = NULL;
1692 Curl_expire(data, 0); /* stop all timers */
1695 case CURLM_STATE_MSGSENT:
1696 return CURLM_OK; /* do nothing */
1699 return CURLM_INTERNAL_ERROR;
1702 if(easy->state < CURLM_STATE_COMPLETED) {
1703 if(CURLE_OK != easy->result) {
1705 * If an error was returned, and we aren't in completed state now,
1706 * then we go to completed and consider this transfer aborted.
1709 /* NOTE: no attempt to disconnect connections must be made
1710 in the case blocks above - cleanup happens only here */
1712 data->state.pipe_broke = FALSE;
1714 if(easy->easy_conn) {
1715 /* if this has a connection, unsubscribe from the pipelines */
1716 easy->easy_conn->writechannel_inuse = FALSE;
1717 easy->easy_conn->readchannel_inuse = FALSE;
1718 Curl_removeHandleFromPipeline(data,
1719 easy->easy_conn->send_pipe);
1720 Curl_removeHandleFromPipeline(data,
1721 easy->easy_conn->recv_pipe);
1722 Curl_removeHandleFromPipeline(data,
1723 easy->easy_conn->done_pipe);
1724 /* Check if we can move pending requests to send pipe */
1725 checkPendPipeline(easy->easy_conn);
1727 if(disconnect_conn) {
1728 /* disconnect properly */
1729 Curl_disconnect(easy->easy_conn, /* dead_connection */ FALSE);
1731 /* This is where we make sure that the easy_conn pointer is reset.
1732 We don't have to do this in every case block above where a
1733 failure is detected */
1734 easy->easy_conn = NULL;
1737 else if(easy->state == CURLM_STATE_CONNECT) {
1738 /* Curl_connect() failed */
1739 (void)Curl_posttransfer(data);
1742 multistate(easy, CURLM_STATE_COMPLETED);
1744 /* if there's still a connection to use, call the progress function */
1745 else if(easy->easy_conn && Curl_pgrsUpdate(easy->easy_conn)) {
1746 /* aborted due to progress callback return code must close the
1748 easy->easy_conn->bits.close = TRUE;
1750 /* if not yet in DONE state, go there, otherwise COMPLETED */
1751 multistate(easy, (easy->state < CURLM_STATE_DONE)?
1752 CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
1753 result = CURLM_CALL_MULTI_PERFORM;
1756 } WHILE_FALSE; /* just to break out from! */
1758 if(CURLM_STATE_COMPLETED == easy->state) {
1759 /* now fill in the Curl_message with this info */
1762 msg->extmsg.msg = CURLMSG_DONE;
1763 msg->extmsg.easy_handle = data;
1764 msg->extmsg.data.result = easy->result;
1766 result = multi_addmsg(multi, msg);
1768 multistate(easy, CURLM_STATE_MSGSENT);
1775 CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
1777 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
1778 struct Curl_one_easy *easy;
1779 CURLMcode returncode=CURLM_OK;
1780 struct Curl_tree *t;
1781 struct timeval now = Curl_tvnow();
1783 if(!GOOD_MULTI_HANDLE(multi))
1784 return CURLM_BAD_HANDLE;
1786 easy=multi->easy.next;
1787 while(easy != &multi->easy) {
1789 struct WildcardData *wc = &easy->easy_handle->wildcard;
1791 if(easy->easy_handle->set.wildcardmatch) {
1793 CURLcode ret = Curl_wildcard_init(wc); /* init wildcard structures */
1795 return CURLM_OUT_OF_MEMORY;
1800 result = multi_runsingle(multi, now, easy);
1801 while(CURLM_CALL_MULTI_PERFORM == result);
1803 if(easy->easy_handle->set.wildcardmatch) {
1804 /* destruct wildcard structures if it is needed */
1805 if(wc->state == CURLWC_DONE || result)
1806 Curl_wildcard_dtor(wc);
1810 returncode = result;
1812 easy = easy->next; /* operate on next handle */
1816 * Simply remove all expired timers from the splay since handles are dealt
1817 * with unconditionally by this function and curl_multi_timeout() requires
1818 * that already passed/handled expire times are removed from the splay.
1820 * It is important that the 'now' value is set at the entry of this function
1821 * and not for the current time as it may have ticked a little while since
1822 * then and then we risk this loop to remove timers that actually have not
1826 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
1828 /* the removed may have another timeout in queue */
1829 (void)add_next_timeout(now, multi, t->payload);
1833 *running_handles = multi->num_alive;
1835 if(CURLM_OK >= returncode)
1836 update_timer(multi);
1841 static void close_all_connections(struct Curl_multi *multi)
1843 struct connectdata *conn;
1845 conn = Curl_conncache_find_first_connection(multi->conn_cache);
1847 conn->data = multi->closure_handle;
1849 /* This will remove the connection from the cache */
1850 (void)Curl_disconnect(conn, FALSE);
1852 conn = Curl_conncache_find_first_connection(multi->conn_cache);
1856 CURLMcode curl_multi_cleanup(CURLM *multi_handle)
1858 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
1859 struct Curl_one_easy *easy;
1860 struct Curl_one_easy *nexteasy;
1862 if(GOOD_MULTI_HANDLE(multi)) {
1863 multi->type = 0; /* not good anymore */
1865 /* Close all the connections in the connection cache */
1866 close_all_connections(multi);
1868 Curl_close(multi->closure_handle);
1869 multi->closure_handle = NULL;
1871 Curl_hash_destroy(multi->sockhash);
1872 multi->sockhash = NULL;
1874 Curl_conncache_destroy(multi->conn_cache);
1875 multi->conn_cache = NULL;
1877 /* remove the pending list of messages */
1878 Curl_llist_destroy(multi->msglist, NULL);
1879 multi->msglist = NULL;
1881 /* remove all easy handles */
1882 easy = multi->easy.next;
1883 while(easy != &multi->easy) {
1884 nexteasy=easy->next;
1885 if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
1886 /* clear out the usage of the shared DNS cache */
1887 Curl_hostcache_clean(easy->easy_handle);
1888 easy->easy_handle->dns.hostcache = NULL;
1889 easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
1892 /* Clear the pointer to the connection cache */
1893 easy->easy_handle->state.conn_cache = NULL;
1895 Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association */
1901 Curl_hash_destroy(multi->hostcache);
1902 multi->hostcache = NULL;
1909 return CURLM_BAD_HANDLE;
1913 * curl_multi_info_read()
1915 * This function is the primary way for a multi/multi_socket application to
1916 * figure out if a transfer has ended. We MUST make this function as fast as
1917 * possible as it will be polled frequently and we MUST NOT scan any lists in
1918 * here to figure out things. We must scale fine to thousands of handles and
1919 * beyond. The current design is fully O(1).
1922 CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
1924 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
1925 struct Curl_message *msg;
1927 *msgs_in_queue = 0; /* default to none */
1929 if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
1930 /* there is one or more messages in the list */
1931 struct curl_llist_element *e;
1933 /* extract the head of the list to return */
1934 e = multi->msglist->head;
1938 /* remove the extracted entry */
1939 Curl_llist_remove(multi->msglist, e, NULL);
1941 *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
1943 return &msg->extmsg;
1950 * singlesocket() checks what sockets we deal with and their "action state"
1951 * and if we have a different state in any of those sockets from last time we
1952 * call the callback accordingly.
1954 static void singlesocket(struct Curl_multi *multi,
1955 struct Curl_one_easy *easy)
1957 curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
1959 struct Curl_sh_entry *entry;
1962 unsigned int curraction;
1963 struct Curl_one_easy *easy_by_hash;
1964 bool remove_sock_from_hash;
1966 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
1967 socks[i] = CURL_SOCKET_BAD;
1969 /* Fill in the 'current' struct with the state as it is now: what sockets to
1970 supervise and for what actions */
1971 curraction = multi_getsock(easy, socks, MAX_SOCKSPEREASYHANDLE);
1973 /* We have 0 .. N sockets already and we get to know about the 0 .. M
1974 sockets we should have from now on. Detect the differences, remove no
1975 longer supervised ones and add new ones */
1977 /* walk over the sockets we got right now */
1978 for(i=0; (i< MAX_SOCKSPEREASYHANDLE) &&
1979 (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
1981 int action = CURL_POLL_NONE;
1985 /* get it from the hash */
1986 entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
1988 if(curraction & GETSOCK_READSOCK(i))
1989 action |= CURL_POLL_IN;
1990 if(curraction & GETSOCK_WRITESOCK(i))
1991 action |= CURL_POLL_OUT;
1994 /* yeps, already present so check if it has the same action set */
1995 if(entry->action == action)
1996 /* same, continue */
2000 /* this is a socket we didn't have before, add it! */
2001 entry = sh_addentry(multi->sockhash, s, easy->easy_handle);
2007 /* we know (entry != NULL) at this point, see the logic above */
2008 if(multi->socket_cb)
2009 multi->socket_cb(easy->easy_handle,
2012 multi->socket_userp,
2015 entry->action = action; /* store the current action state */
2018 num = i; /* number of sockets */
2020 /* when we've walked over all the sockets we should have right now, we must
2021 make sure to detect sockets that are removed */
2022 for(i=0; i< easy->numsocks; i++) {
2024 s = easy->sockets[i];
2025 for(j=0; j<num; j++) {
2027 /* this is still supervised */
2028 s = CURL_SOCKET_BAD;
2032 if(s != CURL_SOCKET_BAD) {
2034 /* this socket has been removed. Tell the app to remove it */
2035 remove_sock_from_hash = TRUE;
2037 entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
2039 /* check if the socket to be removed serves a connection which has
2040 other easy-s in a pipeline. In this case the socket should not be
2042 struct connectdata *easy_conn;
2044 easy_by_hash = entry->easy->multi_pos;
2045 easy_conn = easy_by_hash->easy_conn;
2047 if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
2048 /* the handle should not be removed from the pipe yet */
2049 remove_sock_from_hash = FALSE;
2051 /* Update the sockhash entry to instead point to the next in line
2052 for the recv_pipe, or the first (in case this particular easy
2054 if(entry->easy == easy->easy_handle) {
2055 if(isHandleAtHead(easy->easy_handle, easy_conn->recv_pipe))
2056 entry->easy = easy_conn->recv_pipe->head->next->ptr;
2058 entry->easy = easy_conn->recv_pipe->head->ptr;
2061 if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
2062 /* the handle should not be removed from the pipe yet */
2063 remove_sock_from_hash = FALSE;
2065 /* Update the sockhash entry to instead point to the next in line
2066 for the send_pipe, or the first (in case this particular easy
2068 if(entry->easy == easy->easy_handle) {
2069 if(isHandleAtHead(easy->easy_handle, easy_conn->send_pipe))
2070 entry->easy = easy_conn->send_pipe->head->next->ptr;
2072 entry->easy = easy_conn->send_pipe->head->ptr;
2075 /* Don't worry about overwriting recv_pipe head with send_pipe_head,
2076 when action will be asked on the socket (see multi_socket()), the
2077 head of the correct pipe will be taken according to the
2082 /* just a precaution, this socket really SHOULD be in the hash already
2083 but in case it isn't, we don't have to tell the app to remove it
2084 either since it never got to know about it */
2085 remove_sock_from_hash = FALSE;
2087 if(remove_sock_from_hash) {
2088 /* in this case 'entry' is always non-NULL */
2089 if(multi->socket_cb)
2090 multi->socket_cb(easy->easy_handle,
2093 multi->socket_userp,
2095 sh_delentry(multi->sockhash, s);
2101 memcpy(easy->sockets, socks, num*sizeof(curl_socket_t));
2102 easy->numsocks = num;
2106 * add_next_timeout()
2108 * Each SessionHandle has a list of timeouts. The add_next_timeout() is called
2109 * when it has just been removed from the splay tree because the timeout has
2110 * expired. This function is then to advance in the list to pick the next
2111 * timeout to use (skip the already expired ones) and add this node back to
2112 * the splay tree again.
2114 * The splay tree only has each sessionhandle as a single node and the nearest
2115 * timeout is used to sort it on.
2117 static CURLMcode add_next_timeout(struct timeval now,
2118 struct Curl_multi *multi,
2119 struct SessionHandle *d)
2121 struct timeval *tv = &d->state.expiretime;
2122 struct curl_llist *list = d->state.timeoutlist;
2123 struct curl_llist_element *e;
2125 /* move over the timeout list for this specific handle and remove all
2126 timeouts that are now passed tense and store the next pending
2128 for(e = list->head; e; ) {
2129 struct curl_llist_element *n = e->next;
2130 long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
2132 /* remove outdated entry */
2133 Curl_llist_remove(list, e, NULL);
2135 /* the list is sorted so get out on the first mismatch */
2141 /* clear the expire times within the handles that we remove from the
2147 /* copy the first entry to 'tv' */
2148 memcpy(tv, e->ptr, sizeof(*tv));
2150 /* remove first entry from list */
2151 Curl_llist_remove(list, e, NULL);
2153 /* insert this node again into the splay */
2154 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2155 &d->state.timenode);
2161 static CURLMcode multi_socket(struct Curl_multi *multi,
2165 int *running_handles)
2167 CURLMcode result = CURLM_OK;
2168 struct SessionHandle *data = NULL;
2169 struct Curl_tree *t;
2170 struct timeval now = Curl_tvnow();
2173 struct Curl_one_easy *easyp;
2174 /* *perform() deals with running_handles on its own */
2175 result = curl_multi_perform(multi, running_handles);
2177 /* walk through each easy handle and do the socket state change magic
2179 easyp=multi->easy.next;
2180 while(easyp != &multi->easy) {
2181 singlesocket(multi, easyp);
2182 easyp = easyp->next;
2185 /* or should we fall-through and do the timer-based stuff? */
2188 else if(s != CURL_SOCKET_TIMEOUT) {
2190 struct Curl_sh_entry *entry =
2191 Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
2194 /* Unmatched socket, we can't act on it but we ignore this fact. In
2195 real-world tests it has been proved that libevent can in fact give
2196 the application actions even though the socket was just previously
2197 asked to get removed, so thus we better survive stray socket actions
2198 and just move on. */
2203 if(data->magic != CURLEASY_MAGIC_NUMBER)
2204 /* bad bad bad bad bad bad bad */
2205 return CURLM_INTERNAL_ERROR;
2207 /* If the pipeline is enabled, take the handle which is in the head of
2208 the pipeline. If we should write into the socket, take the send_pipe
2209 head. If we should read from the socket, take the recv_pipe head. */
2210 if(data->set.one_easy->easy_conn) {
2211 if((ev_bitmask & CURL_POLL_OUT) &&
2212 data->set.one_easy->easy_conn->send_pipe &&
2213 data->set.one_easy->easy_conn->send_pipe->head)
2214 data = data->set.one_easy->easy_conn->send_pipe->head->ptr;
2215 else if((ev_bitmask & CURL_POLL_IN) &&
2216 data->set.one_easy->easy_conn->recv_pipe &&
2217 data->set.one_easy->easy_conn->recv_pipe->head)
2218 data = data->set.one_easy->easy_conn->recv_pipe->head->ptr;
2221 if(data->set.one_easy->easy_conn &&
2222 !(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2223 /* set socket event bitmask if they're not locked */
2224 data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
2227 result = multi_runsingle(multi, now, data->set.one_easy);
2228 while(CURLM_CALL_MULTI_PERFORM == result);
2230 if(data->set.one_easy->easy_conn &&
2231 !(data->set.one_easy->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2232 /* clear the bitmask only if not locked */
2233 data->set.one_easy->easy_conn->cselect_bits = 0;
2235 if(CURLM_OK >= result)
2236 /* get the socket(s) and check if the state has been changed since
2238 singlesocket(multi, data->set.one_easy);
2240 /* Now we fall-through and do the timer-based stuff, since we don't want
2241 to force the user to have to deal with timeouts as long as at least
2242 one connection in fact has traffic. */
2244 data = NULL; /* set data to NULL again to avoid calling
2245 multi_runsingle() in case there's no need to */
2249 now.tv_usec += 40000; /* compensate for bad precision timers that might've
2250 triggered too early */
2251 if(now.tv_usec >= 1000000) {
2253 now.tv_usec -= 1000000;
2257 * The loop following here will go on as long as there are expire-times left
2258 * to process in the splay and 'data' will be re-assigned for every expired
2259 * handle we deal with.
2262 /* the first loop lap 'data' can be NULL */
2265 result = multi_runsingle(multi, now, data->set.one_easy);
2266 while(CURLM_CALL_MULTI_PERFORM == result);
2268 if(CURLM_OK >= result)
2269 /* get the socket(s) and check if the state has been changed since
2271 singlesocket(multi, data->set.one_easy);
2274 /* Check if there's one (more) expired timer to deal with! This function
2275 extracts a matching node if there is one */
2277 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2279 data = t->payload; /* assign this for next loop */
2280 (void)add_next_timeout(now, multi, t->payload);
2285 *running_handles = multi->num_alive;
2289 #undef curl_multi_setopt
2290 CURLMcode curl_multi_setopt(CURLM *multi_handle,
2291 CURLMoption option, ...)
2293 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
2294 CURLMcode res = CURLM_OK;
2297 if(!GOOD_MULTI_HANDLE(multi))
2298 return CURLM_BAD_HANDLE;
2300 va_start(param, option);
2303 case CURLMOPT_SOCKETFUNCTION:
2304 multi->socket_cb = va_arg(param, curl_socket_callback);
2306 case CURLMOPT_SOCKETDATA:
2307 multi->socket_userp = va_arg(param, void *);
2309 case CURLMOPT_PIPELINING:
2310 multi->pipelining_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
2312 case CURLMOPT_TIMERFUNCTION:
2313 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
2315 case CURLMOPT_TIMERDATA:
2316 multi->timer_userp = va_arg(param, void *);
2318 case CURLMOPT_MAXCONNECTS:
2319 multi->maxconnects = va_arg(param, long);
2322 res = CURLM_UNKNOWN_OPTION;
2329 /* we define curl_multi_socket() in the public multi.h header */
2330 #undef curl_multi_socket
2332 CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
2333 int *running_handles)
2335 CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
2336 0, running_handles);
2337 if(CURLM_OK >= result)
2338 update_timer((struct Curl_multi *)multi_handle);
2342 CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
2343 int ev_bitmask, int *running_handles)
2345 CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
2346 ev_bitmask, running_handles);
2347 if(CURLM_OK >= result)
2348 update_timer((struct Curl_multi *)multi_handle);
2352 CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
2355 CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
2356 TRUE, CURL_SOCKET_BAD, 0, running_handles);
2357 if(CURLM_OK >= result)
2358 update_timer((struct Curl_multi *)multi_handle);
2362 static CURLMcode multi_timeout(struct Curl_multi *multi,
2365 static struct timeval tv_zero = {0,0};
2367 if(multi->timetree) {
2368 /* we have a tree of expire times */
2369 struct timeval now = Curl_tvnow();
2371 /* splay the lowest to the bottom */
2372 multi->timetree = Curl_splay(tv_zero, multi->timetree);
2374 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
2375 /* some time left before expiration */
2376 *timeout_ms = curlx_tvdiff(multi->timetree->key, now);
2379 * Since we only provide millisecond resolution on the returned value
2380 * and the diff might be less than one millisecond here, we don't
2381 * return zero as that may cause short bursts of busyloops on fast
2382 * processors while the diff is still present but less than one
2383 * millisecond! instead we return 1 until the time is ripe.
2388 /* 0 means immediately */
2397 CURLMcode curl_multi_timeout(CURLM *multi_handle,
2400 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
2402 /* First, make some basic checks that the CURLM handle is a good handle */
2403 if(!GOOD_MULTI_HANDLE(multi))
2404 return CURLM_BAD_HANDLE;
2406 return multi_timeout(multi, timeout_ms);
2410 * Tell the application it should update its timers, if it subscribes to the
2411 * update timer callback.
2413 static int update_timer(struct Curl_multi *multi)
2417 if(!multi->timer_cb)
2419 if(multi_timeout(multi, &timeout_ms)) {
2422 if(timeout_ms < 0) {
2423 static const struct timeval none={0,0};
2424 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
2425 multi->timer_lastcall = none;
2426 /* there's no timeout now but there was one previously, tell the app to
2428 return multi->timer_cb((CURLM*)multi, -1, multi->timer_userp);
2433 /* When multi_timeout() is done, multi->timetree points to the node with the
2434 * timeout we got the (relative) time-out time for. We can thus easily check
2435 * if this is the same (fixed) time as we got in a previous call and then
2436 * avoid calling the callback again. */
2437 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
2440 multi->timer_lastcall = multi->timetree->key;
2442 return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
2445 static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
2446 struct connectdata *conn)
2448 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
2449 struct curl_llist_element *sendhead = conn->send_pipe->head;
2450 struct curl_llist *pipeline;
2453 if(!Curl_isPipeliningEnabled(handle) ||
2455 pipeline = conn->send_pipe;
2457 if(conn->server_supports_pipelining &&
2458 pipeLen < MAX_PIPELINE_LENGTH)
2459 pipeline = conn->send_pipe;
2461 pipeline = conn->pend_pipe;
2464 rc = Curl_addHandleToPipeline(handle, pipeline);
2466 if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
2467 /* this is a new one as head, expire it */
2468 conn->writechannel_inuse = FALSE; /* not in use yet */
2470 infof(conn->data, "%p is at send pipe head!\n",
2471 conn->send_pipe->head->ptr);
2473 Curl_expire(conn->send_pipe->head->ptr, 1);
2479 static int checkPendPipeline(struct connectdata *conn)
2482 struct curl_llist_element *sendhead = conn->send_pipe->head;
2484 size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
2485 if(conn->server_supports_pipelining || pipeLen == 0) {
2486 struct curl_llist_element *curr = conn->pend_pipe->head;
2487 const size_t maxPipeLen =
2488 conn->server_supports_pipelining ? MAX_PIPELINE_LENGTH : 1;
2490 while(pipeLen < maxPipeLen && curr) {
2491 Curl_llist_move(conn->pend_pipe, curr,
2492 conn->send_pipe, conn->send_pipe->tail);
2493 Curl_pgrsTime(curr->ptr, TIMER_PRETRANSFER);
2494 ++result; /* count how many handles we moved */
2495 curr = conn->pend_pipe->head;
2501 conn->now = Curl_tvnow();
2502 /* something moved, check for a new send pipeline leader */
2503 if(sendhead != conn->send_pipe->head) {
2504 /* this is a new one as head, expire it */
2505 conn->writechannel_inuse = FALSE; /* not in use yet */
2507 infof(conn->data, "%p is at send pipe head!\n",
2508 conn->send_pipe->head->ptr);
2510 Curl_expire(conn->send_pipe->head->ptr, 1);
2517 /* Move this transfer from the sending list to the receiving list.
2519 Pay special attention to the new sending list "leader" as it needs to get
2520 checked to update what sockets it acts on.
2523 static void moveHandleFromSendToRecvPipeline(struct SessionHandle *handle,
2524 struct connectdata *conn)
2526 struct curl_llist_element *curr;
2528 curr = conn->send_pipe->head;
2530 if(curr->ptr == handle) {
2531 Curl_llist_move(conn->send_pipe, curr,
2532 conn->recv_pipe, conn->recv_pipe->tail);
2534 if(conn->send_pipe->head) {
2535 /* Since there's a new easy handle at the start of the send pipeline,
2536 set its timeout value to 1ms to make it trigger instantly */
2537 conn->writechannel_inuse = FALSE; /* not used now */
2539 infof(conn->data, "%p is at send pipe head B!\n",
2540 conn->send_pipe->head->ptr);
2542 Curl_expire(conn->send_pipe->head->ptr, 1);
2545 /* The receiver's list is not really interesting here since either this
2546 handle is now first in the list and we'll deal with it soon, or
2547 another handle is already first and thus is already taken care of */
2549 break; /* we're done! */
2555 static void moveHandleFromRecvToDonePipeline(struct SessionHandle *handle,
2556 struct connectdata *conn)
2558 struct curl_llist_element *curr;
2560 curr = conn->recv_pipe->head;
2562 if(curr->ptr == handle) {
2563 Curl_llist_move(conn->recv_pipe, curr,
2564 conn->done_pipe, conn->done_pipe->tail);
2570 static bool isHandleAtHead(struct SessionHandle *handle,
2571 struct curl_llist *pipeline)
2573 struct curl_llist_element *curr = pipeline->head;
2575 return (curr->ptr == handle) ? TRUE : FALSE;
2581 * multi_freetimeout()
2583 * Callback used by the llist system when a single timeout list entry is
2586 static void multi_freetimeout(void *user, void *entryptr)
2590 /* the entry was plain malloc()'ed */
2595 * multi_addtimeout()
2597 * Add a timestamp to the list of timeouts. Keep the list sorted so that head
2598 * of list is always the timeout nearest in time.
2602 multi_addtimeout(struct curl_llist *timeoutlist,
2603 struct timeval *stamp)
2605 struct curl_llist_element *e;
2606 struct timeval *timedup;
2607 struct curl_llist_element *prev = NULL;
2609 timedup = malloc(sizeof(*timedup));
2611 return CURLM_OUT_OF_MEMORY;
2613 /* copy the timestamp */
2614 memcpy(timedup, stamp, sizeof(*timedup));
2616 if(Curl_llist_count(timeoutlist)) {
2617 /* find the correct spot in the list */
2618 for(e = timeoutlist->head; e; e = e->next) {
2619 struct timeval *checktime = e->ptr;
2620 long diff = curlx_tvdiff(*checktime, *timedup);
2628 this is the first timeout on the list */
2630 if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
2632 return CURLM_OUT_OF_MEMORY;
2641 * given a number of milliseconds from now to use to set the 'act before
2642 * this'-time for the transfer, to be extracted by curl_multi_timeout()
2644 * Note that the timeout will be added to a queue of timeouts if it defines a
2645 * moment in time that is later than the current head of queue.
2647 * Pass zero to clear all timeout values for this handle.
2649 void Curl_expire(struct SessionHandle *data, long milli)
2651 struct Curl_multi *multi = data->multi;
2652 struct timeval *nowp = &data->state.expiretime;
2655 /* this is only interesting for multi-interface using libcurl, and only
2656 while there is still a multi interface struct remaining! */
2661 /* No timeout, clear the time data. */
2662 if(nowp->tv_sec || nowp->tv_usec) {
2663 /* Since this is an cleared time, we must remove the previous entry from
2665 struct curl_llist *list = data->state.timeoutlist;
2667 rc = Curl_splayremovebyaddr(multi->timetree,
2668 &data->state.timenode,
2671 infof(data, "Internal error clearing splay node = %d\n", rc);
2673 /* flush the timeout list too */
2674 while(list->size > 0)
2675 Curl_llist_remove(list, list->tail, NULL);
2678 infof(data, "Expire cleared\n");
2688 set.tv_sec += milli/1000;
2689 set.tv_usec += (milli%1000)*1000;
2691 if(set.tv_usec >= 1000000) {
2693 set.tv_usec -= 1000000;
2696 if(nowp->tv_sec || nowp->tv_usec) {
2697 /* This means that the struct is added as a node in the splay tree.
2698 Compare if the new time is earlier, and only remove-old/add-new if it
2700 long diff = curlx_tvdiff(set, *nowp);
2702 /* the new expire time was later so just add it to the queue
2704 multi_addtimeout(data->state.timeoutlist, &set);
2708 /* the new time is newer than the presently set one, so add the current
2709 to the queue and update the head */
2710 multi_addtimeout(data->state.timeoutlist, nowp);
2712 /* Since this is an updated time, we must remove the previous entry from
2713 the splay tree first and then re-add the new value */
2714 rc = Curl_splayremovebyaddr(multi->timetree,
2715 &data->state.timenode,
2718 infof(data, "Internal error removing splay node = %d\n", rc);
2722 data->state.timenode.payload = data;
2723 multi->timetree = Curl_splayinsert(*nowp,
2725 &data->state.timenode);
2728 Curl_splayprint(multi->timetree, 0, TRUE);
2732 CURLMcode curl_multi_assign(CURLM *multi_handle,
2733 curl_socket_t s, void *hashp)
2735 struct Curl_sh_entry *there = NULL;
2736 struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
2738 if(s != CURL_SOCKET_BAD)
2739 there = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(curl_socket_t));
2742 return CURLM_BAD_SOCKET;
2744 there->socketp = hashp;
2750 void Curl_multi_dump(const struct Curl_multi *multi_handle)
2752 struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
2753 struct Curl_one_easy *easy;
2755 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
2756 multi->num_easy, multi->num_alive);
2757 for(easy=multi->easy.next; easy != &multi->easy; easy = easy->next) {
2758 if(easy->state < CURLM_STATE_COMPLETED) {
2759 /* only display handles that are not completed */
2760 fprintf(stderr, "handle %p, state %s, %d sockets\n",
2761 (void *)easy->easy_handle,
2762 statename[easy->state], easy->numsocks);
2763 for(i=0; i < easy->numsocks; i++) {
2764 curl_socket_t s = easy->sockets[i];
2765 struct Curl_sh_entry *entry =
2766 Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
2768 fprintf(stderr, "%d ", (int)s);
2770 fprintf(stderr, "INTERNAL CONFUSION\n");
2773 fprintf(stderr, "[%s %s] ",
2774 entry->action&CURL_POLL_IN?"RECVING":"",
2775 entry->action&CURL_POLL_OUT?"SENDING":"");
2778 fprintf(stderr, "\n");