Lines Matching full:multi
96 static CURLMcode singlesocket(struct Curl_multi *multi,
99 struct Curl_multi *multi,
101 static CURLMcode multi_timeout(struct Curl_multi *multi,
103 static void process_pending_handles(struct Curl_multi *multi);
202 DEBUGASSERT(data->multi->num_alive > 0); in mstate()
203 data->multi->num_alive--; in mstate()
384 * the list kept in the multi handle.
386 static CURLMcode multi_addmsg(struct Curl_multi *multi, in multi_addmsg() argument
389 Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg, in multi_addmsg()
398 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); in Curl_multi_handle() local
400 if(!multi) in Curl_multi_handle()
403 multi->magic = CURL_MULTI_HANDLE; in Curl_multi_handle()
405 Curl_init_dnscache(&multi->hostcache, dnssize); in Curl_multi_handle()
407 sh_init(&multi->sockhash, hashsize); in Curl_multi_handle()
409 if(Curl_conncache_init(&multi->conn_cache, chashsize)) in Curl_multi_handle()
412 Curl_llist_init(&multi->msglist, NULL); in Curl_multi_handle()
413 Curl_llist_init(&multi->pending, NULL); in Curl_multi_handle()
415 multi->multiplexing = TRUE; in Curl_multi_handle()
418 multi->maxconnects = -1; in Curl_multi_handle()
419 multi->max_concurrent_streams = 100; in Curl_multi_handle()
422 multi->wsa_event = WSACreateEvent(); in Curl_multi_handle()
423 if(multi->wsa_event == WSA_INVALID_EVENT) in Curl_multi_handle()
427 if(wakeup_create(multi->wakeup_pair) < 0) { in Curl_multi_handle()
428 multi->wakeup_pair[0] = CURL_SOCKET_BAD; in Curl_multi_handle()
429 multi->wakeup_pair[1] = CURL_SOCKET_BAD; in Curl_multi_handle()
431 else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 || in Curl_multi_handle()
432 curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) { in Curl_multi_handle()
433 wakeup_close(multi->wakeup_pair[0]); in Curl_multi_handle()
434 wakeup_close(multi->wakeup_pair[1]); in Curl_multi_handle()
435 multi->wakeup_pair[0] = CURL_SOCKET_BAD; in Curl_multi_handle()
436 multi->wakeup_pair[1] = CURL_SOCKET_BAD; in Curl_multi_handle()
441 return multi; in Curl_multi_handle()
445 sockhash_destroy(&multi->sockhash); in Curl_multi_handle()
446 Curl_hash_destroy(&multi->hostcache); in Curl_multi_handle()
447 Curl_conncache_destroy(&multi->conn_cache); in Curl_multi_handle()
448 free(multi); in Curl_multi_handle()
459 static void link_easy(struct Curl_multi *multi, in link_easy() argument
464 if(multi->easyp) { in link_easy()
465 struct Curl_easy *last = multi->easylp; in link_easy()
468 multi->easylp = data; /* the new last node */ in link_easy()
473 multi->easylp = multi->easyp = data; /* both first and last */ in link_easy()
478 static void unlink_easy(struct Curl_multi *multi, in unlink_easy() argument
485 multi->easyp = data->next; /* point to first node */ in unlink_easy()
491 multi->easylp = data->prev; /* point to last node */ in unlink_easy()
495 CURLMcode curl_multi_add_handle(struct Curl_multi *multi, in curl_multi_add_handle() argument
500 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_add_handle()
508 adding to more than one multi stack */ in curl_multi_add_handle()
509 if(data->multi) in curl_multi_add_handle()
512 if(multi->in_callback) in curl_multi_add_handle()
515 if(multi->dead) { in curl_multi_add_handle()
519 if(multi->num_alive) in curl_multi_add_handle()
521 multi->dead = FALSE; in curl_multi_add_handle()
529 * modification of easy nor multi handle allowed before this except for in curl_multi_add_handle()
530 * potential multi's connection cache growing which won't be undone in this in curl_multi_add_handle()
536 /* make the Curl_easy refer back to this multi handle - before Curl_expire() in curl_multi_add_handle()
538 data->multi = multi; in curl_multi_add_handle()
558 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); in curl_multi_add_handle()
560 rc = Curl_update_timer(multi); in curl_multi_add_handle()
567 /* for multi interface connections, we share DNS cache automatically if the in curl_multi_add_handle()
571 data->dns.hostcache = &multi->hostcache; in curl_multi_add_handle()
575 /* Point to the shared or multi handle connection cache */ in curl_multi_add_handle()
579 data->state.conn_cache = &multi->conn_cache; in curl_multi_add_handle()
587 data->psl = &multi->psl; in curl_multi_add_handle()
590 link_easy(multi, data); in curl_multi_add_handle()
593 multi->num_easy++; in curl_multi_add_handle()
596 multi->num_alive++; in curl_multi_add_handle()
616 * Curl_hash_print(&multi->sockhash, debug_print_sock_hash);
682 process_pending_handles(data->multi); /* connection / multiplex */ in multi_done()
792 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, in curl_multi_remove_handle() argument
801 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_remove_handle()
809 if(!data->multi) in curl_multi_remove_handle()
812 /* Prevent users from trying to remove an easy handle from the wrong multi */ in curl_multi_remove_handle()
813 if(data->multi != multi) in curl_multi_remove_handle()
816 if(multi->in_callback) in curl_multi_remove_handle()
826 multi->num_alive--; in curl_multi_remove_handle()
846 /* The timer must be shut down before data->multi is set to NULL, else the in curl_multi_remove_handle()
854 Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); in curl_multi_remove_handle()
857 /* stop using the multi handle's DNS cache, *after* the possible in curl_multi_remove_handle()
871 (void)singlesocket(multi, easy); /* to let the application know what sockets in curl_multi_remove_handle()
878 /* This removes a handle that was part the multi interface that used in curl_multi_remove_handle()
882 anymore once removed from the multi handle in curl_multi_remove_handle()
903 if(data->psl == &multi->psl) in curl_multi_remove_handle()
908 since we're not part of that multi handle anymore */ in curl_multi_remove_handle()
911 data->multi = NULL; /* clear the association to this multi handle */ in curl_multi_remove_handle()
916 for(e = multi->msglist.head; e; e = e->next) { in curl_multi_remove_handle()
920 Curl_llist_remove(&multi->msglist, e, NULL); in curl_multi_remove_handle()
928 for(e = multi->pending.head; e; e = e->next) { in curl_multi_remove_handle()
932 Curl_llist_remove(&multi->pending, e, NULL); in curl_multi_remove_handle()
937 unlink_easy(multi, data); in curl_multi_remove_handle()
941 multi->num_easy--; /* one less to care about now */ in curl_multi_remove_handle()
943 process_pending_handles(multi); in curl_multi_remove_handle()
945 rc = Curl_update_timer(multi); in curl_multi_remove_handle()
952 bool Curl_multiplex_wanted(const struct Curl_multi *multi) in Curl_multiplex_wanted() argument
954 return (multi && (multi->multiplexing)); in Curl_multiplex_wanted()
1060 CURLMcode curl_multi_fdset(struct Curl_multi *multi, in curl_multi_fdset() argument
1073 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_fdset()
1076 if(multi->in_callback) in curl_multi_fdset()
1079 data = multi->easyp; in curl_multi_fdset()
1138 static CURLMcode multi_wait(struct Curl_multi *multi, argument
1159 DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
1165 if(!GOOD_MULTI_HANDLE(multi))
1168 if(multi->in_callback)
1174 /* Count up how many fds we have from the multi handle */
1175 data = multi->easyp;
1201 (void)multi_timeout(multi, &timeout_internal);
1212 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1235 data = multi->easyp;
1269 if(WSAEventSelect(s, multi->wsa_event, mask) != 0) {
1293 if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) {
1312 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1313 ufds[nfds].fd = multi->wakeup_pair[0];
1342 WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
1367 WSAEventSelect(s, multi->wsa_event, 0);
1386 data = multi->easyp;
1397 WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
1409 WSAResetEvent(multi->wsa_event);
1412 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1421 nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf));
1449 if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
1452 /* when there are no easy handles in the multi, this holds a -1
1463 CURLMcode curl_multi_wait(struct Curl_multi *multi, argument
1469 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
1473 CURLMcode curl_multi_poll(struct Curl_multi *multi, argument
1479 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
1483 CURLMcode curl_multi_wakeup(struct Curl_multi *multi) argument
1490 if(!GOOD_MULTI_HANDLE(multi))
1495 if(WSASetEvent(multi->wsa_event))
1501 if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
1514 if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1543 static bool multi_ischanged(struct Curl_multi *multi, bool clear) argument
1545 bool retval = multi->recheckstate;
1547 multi->recheckstate = FALSE;
1551 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, argument
1557 if(multi->in_callback)
1560 rc = curl_multi_add_handle(multi, data);
1592 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1667 * over from the multi interface until the connection phase is done on
1687 * We are DOING this is being called over and over from the multi interface
1756 * POST/PUT with multi-pass authentication when a sending was denied and a
1854 static void set_in_callback(struct Curl_multi *multi, bool value) argument
1856 multi->in_callback = value;
1859 static CURLMcode multi_runsingle(struct Curl_multi *multi, argument
1878 if(multi->dead) {
1879 /* a multi-level callback returned error before, meaning every individual
1888 if(!multi->warned) {
1892 multi->warned = true;
1902 if(multi_ischanged(multi, TRUE)) {
1903 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
1904 process_pending_handles(multi); /* multiplexed */
1972 Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
1980 process_pending_handles(data->multi);
2041 rc = singlesocket(multi, data);
2343 process_pending_handles(multi); /* multiplexed */
2572 process_pending_handles(multi); /* multiplexing */
2612 !multi_ischanged(multi, false)) {
2635 process_pending_handles(multi); /* connection */
2690 rc = multi_addmsg(multi, msg);
2695 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2702 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) argument
2709 if(!GOOD_MULTI_HANDLE(multi))
2712 if(multi->in_callback)
2715 data = multi->easyp;
2729 result = multi_runsingle(multi, &now, data);
2748 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2751 (void)add_next_timeout(now, multi, t->payload);
2755 *running_handles = multi->num_alive;
2758 returncode = Curl_update_timer(multi);
2763 CURLMcode curl_multi_cleanup(struct Curl_multi *multi) argument
2768 if(GOOD_MULTI_HANDLE(multi)) {
2769 if(multi->in_callback)
2772 multi->magic = 0; /* not good anymore */
2775 data = multi->easyp;
2790 data->multi = NULL; /* clear the association */
2793 if(data->psl == &multi->psl)
2801 Curl_conncache_close_all_connections(&multi->conn_cache);
2803 sockhash_destroy(&multi->sockhash);
2804 Curl_conncache_destroy(&multi->conn_cache);
2805 Curl_hash_destroy(&multi->hostcache);
2806 Curl_psl_destroy(&multi->psl);
2809 WSACloseEvent(multi->wsa_event);
2812 wakeup_close(multi->wakeup_pair[0]);
2813 wakeup_close(multi->wakeup_pair[1]);
2818 Curl_free_multi_ssl_backend_data(multi->ssl_backend_data);
2821 free(multi);
2831 * This function is the primary way for a multi/multi_socket application to
2838 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) argument
2844 if(GOOD_MULTI_HANDLE(multi) &&
2845 !multi->in_callback &&
2846 Curl_llist_count(&multi->msglist)) {
2851 e = multi->msglist.head;
2856 Curl_llist_remove(&multi->msglist, e, NULL);
2858 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
2870 static CURLMcode singlesocket(struct Curl_multi *multi, argument
2905 entry = sh_getentry(&multi->sockhash, s);
2926 entry = sh_addentry(&multi->sockhash, s);
2966 if(multi->socket_cb) {
2967 set_in_callback(multi, TRUE);
2968 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
2970 set_in_callback(multi, FALSE);
2972 multi->dead = TRUE;
2998 entry = sh_getentry(&multi->sockhash, s);
3010 if(multi->socket_cb) {
3011 set_in_callback(multi, TRUE);
3012 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3013 multi->socket_userp, entry->socketp);
3014 set_in_callback(multi, FALSE);
3016 multi->dead = TRUE;
3020 sh_delentry(entry, &multi->sockhash, s);
3040 if(singlesocket(data->multi, data))
3060 struct Curl_multi *multi = data->multi; local
3061 if(multi) {
3063 a multi handle, and only then this is necessary */
3064 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3068 if(multi->socket_cb) {
3069 set_in_callback(multi, TRUE);
3070 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3071 multi->socket_userp, entry->socketp);
3072 set_in_callback(multi, FALSE);
3076 sh_delentry(entry, &multi->sockhash, s);
3078 /* This just marks the multi handle as "dead" without returning an
3081 multi->dead = TRUE;
3100 struct Curl_multi *multi, argument
3137 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
3143 static CURLMcode multi_socket(struct Curl_multi *multi, argument
3156 result = curl_multi_perform(multi, running_handles);
3161 data = multi->easyp;
3163 result = singlesocket(multi, data);
3172 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3216 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
3230 result = multi_runsingle(multi, &now, data);
3236 result = singlesocket(multi, data);
3245 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3248 (void)add_next_timeout(now, multi, t->payload);
3253 *running_handles = multi->num_alive;
3258 CURLMcode curl_multi_setopt(struct Curl_multi *multi, argument
3264 if(!GOOD_MULTI_HANDLE(multi))
3267 if(multi->in_callback)
3274 multi->socket_cb = va_arg(param, curl_socket_callback);
3277 multi->socket_userp = va_arg(param, void *);
3280 multi->push_cb = va_arg(param, curl_push_callback);
3283 multi->push_userp = va_arg(param, void *);
3286 multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0;
3289 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3292 multi->timer_userp = va_arg(param, void *);
3295 multi->maxconnects = va_arg(param, long);
3298 multi->max_host_connections = va_arg(param, long);
3301 multi->max_total_connections = va_arg(param, long);
3319 multi->max_concurrent_streams = curlx_sltoui(streams);
3330 /* we define curl_multi_socket() in the public multi.h header */
3333 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, argument
3337 if(multi->in_callback)
3339 result = multi_socket(multi, FALSE, s, 0, running_handles);
3341 result = Curl_update_timer(multi);
3345 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, argument
3349 if(multi->in_callback)
3351 result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3353 result = Curl_update_timer(multi);
3357 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) argument
3360 if(multi->in_callback)
3362 result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3364 result = Curl_update_timer(multi);
3368 static CURLMcode multi_timeout(struct Curl_multi *multi, argument
3373 if(multi->dead) {
3378 if(multi->timetree) {
3383 multi->timetree = Curl_splay(tv_zero, multi->timetree);
3385 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
3387 timediff_t diff = Curl_timediff(multi->timetree->key, now);
3412 CURLMcode curl_multi_timeout(struct Curl_multi *multi, argument
3416 if(!GOOD_MULTI_HANDLE(multi))
3419 if(multi->in_callback)
3422 return multi_timeout(multi, timeout_ms);
3429 CURLMcode Curl_update_timer(struct Curl_multi *multi) argument
3434 if(!multi->timer_cb || multi->dead)
3436 if(multi_timeout(multi, &timeout_ms)) {
3441 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
3442 multi->timer_lastcall = none;
3445 set_in_callback(multi, TRUE);
3446 rc = multi->timer_cb(multi, -1, multi->timer_userp);
3447 set_in_callback(multi, FALSE);
3449 multi->dead = TRUE;
3457 /* When multi_timeout() is done, multi->timetree points to the node with the
3461 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
3464 multi->timer_lastcall = multi->timetree->key;
3466 set_in_callback(multi, TRUE);
3467 rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3468 set_in_callback(multi, FALSE);
3470 multi->dead = TRUE;
3552 struct Curl_multi *multi = data->multi; local
3556 /* this is only interesting while there is still an associated multi struct
3558 if(!multi)
3594 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3595 &multi->timetree);
3604 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
3627 struct Curl_multi *multi = data->multi; local
3630 /* this is only interesting while there is still an associated multi struct
3632 if(!multi)
3641 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3642 &multi->timetree);
3662 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, argument
3667 there = sh_getentry(&multi->sockhash, s);
3677 size_t Curl_multi_max_host_connections(struct Curl_multi *multi) argument
3679 return multi ? multi->max_host_connections : 0;
3682 size_t Curl_multi_max_total_connections(struct Curl_multi *multi) argument
3684 return multi ? multi->max_total_connections : 0;
3696 DEBUGASSERT(data->multi);
3702 process_pending_handles(data->multi);
3705 static void process_pending_handles(struct Curl_multi *multi) argument
3707 struct Curl_llist_element *e = multi->pending.head;
3716 Curl_llist_remove(&multi->pending, e, NULL);
3732 else if(data->multi)
3733 data->multi->in_callback = value;
3739 return ((easy->multi && easy->multi->in_callback) ||
3744 void Curl_multi_dump(struct Curl_multi *multi) argument
3748 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
3749 multi->num_easy, multi->num_alive);
3750 for(data = multi->easyp; data; data = data->next) {
3758 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3776 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi) argument
3778 DEBUGASSERT(multi);
3779 return multi->max_concurrent_streams;