Lines Matching full:multi

74 static CURLMcode singlesocket(struct Curl_multi *multi,
77 struct Curl_multi *multi,
79 static CURLMcode multi_timeout(struct Curl_multi *multi,
81 static void process_pending_handles(struct Curl_multi *multi);
173 DEBUGASSERT(data->multi->num_alive > 0); in mstate()
174 data->multi->num_alive--; in mstate()
338 * the list kept in the multi handle.
340 static CURLMcode multi_addmsg(struct Curl_multi *multi, in multi_addmsg() argument
343 Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg, in multi_addmsg()
351 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); in Curl_multi_handle() local
353 if(!multi) in Curl_multi_handle()
356 multi->type = CURL_MULTI_HANDLE; in Curl_multi_handle()
358 if(Curl_mk_dnscache(&multi->hostcache)) in Curl_multi_handle()
361 if(sh_init(&multi->sockhash, hashsize)) in Curl_multi_handle()
364 if(Curl_conncache_init(&multi->conn_cache, chashsize)) in Curl_multi_handle()
367 Curl_llist_init(&multi->msglist, NULL); in Curl_multi_handle()
368 Curl_llist_init(&multi->pending, NULL); in Curl_multi_handle()
370 multi->multiplexing = TRUE; in Curl_multi_handle()
373 multi->maxconnects = -1; in Curl_multi_handle()
374 multi->max_concurrent_streams = 100; in Curl_multi_handle()
375 multi->ipv6_works = Curl_ipv6works(NULL); in Curl_multi_handle()
378 multi->wsa_event = WSACreateEvent(); in Curl_multi_handle()
379 if(multi->wsa_event == WSA_INVALID_EVENT) in Curl_multi_handle()
383 if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) { in Curl_multi_handle()
384 multi->wakeup_pair[0] = CURL_SOCKET_BAD; in Curl_multi_handle()
385 multi->wakeup_pair[1] = CURL_SOCKET_BAD; in Curl_multi_handle()
387 else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 || in Curl_multi_handle()
388 curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) { in Curl_multi_handle()
389 sclose(multi->wakeup_pair[0]); in Curl_multi_handle()
390 sclose(multi->wakeup_pair[1]); in Curl_multi_handle()
391 multi->wakeup_pair[0] = CURL_SOCKET_BAD; in Curl_multi_handle()
392 multi->wakeup_pair[1] = CURL_SOCKET_BAD; in Curl_multi_handle()
397 return multi; in Curl_multi_handle()
401 Curl_hash_destroy(&multi->sockhash); in Curl_multi_handle()
402 Curl_hash_destroy(&multi->hostcache); in Curl_multi_handle()
403 Curl_conncache_destroy(&multi->conn_cache); in Curl_multi_handle()
404 Curl_llist_destroy(&multi->msglist, NULL); in Curl_multi_handle()
405 Curl_llist_destroy(&multi->pending, NULL); in Curl_multi_handle()
407 free(multi); in Curl_multi_handle()
417 CURLMcode curl_multi_add_handle(struct Curl_multi *multi, in curl_multi_add_handle() argument
421 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_add_handle()
429 adding to more than one multi stack */ in curl_multi_add_handle()
430 if(data->multi) in curl_multi_add_handle()
433 if(multi->in_callback) in curl_multi_add_handle()
441 * modification of easy nor multi handle allowed before this except for in curl_multi_add_handle()
442 * potential multi's connection cache growing which won't be undone in this in curl_multi_add_handle()
451 /* for multi interface connections, we share DNS cache automatically if the in curl_multi_add_handle()
455 data->dns.hostcache = &multi->hostcache; in curl_multi_add_handle()
459 /* Point to the shared or multi handle connection cache */ in curl_multi_add_handle()
463 data->state.conn_cache = &multi->conn_cache; in curl_multi_add_handle()
471 data->psl = &multi->psl; in curl_multi_add_handle()
476 if(multi->easyp) { in curl_multi_add_handle()
477 struct Curl_easy *last = multi->easylp; in curl_multi_add_handle()
480 multi->easylp = data; /* the new last node */ in curl_multi_add_handle()
485 multi->easylp = multi->easyp = data; /* both first and last */ in curl_multi_add_handle()
488 /* make the Curl_easy refer back to this multi handle */ in curl_multi_add_handle()
489 data->multi = multi; in curl_multi_add_handle()
500 multi->num_easy++; in curl_multi_add_handle()
503 multi->num_alive++; in curl_multi_add_handle()
515 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); in curl_multi_add_handle()
529 Curl_update_timer(multi); in curl_multi_add_handle()
536 * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
600 process_pending_handles(data->multi); /* connection / multiplex */ in multi_done()
719 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, in curl_multi_remove_handle() argument
728 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_remove_handle()
736 if(!data->multi) in curl_multi_remove_handle()
739 /* Prevent users from trying to remove an easy handle from the wrong multi */ in curl_multi_remove_handle()
740 if(data->multi != multi) in curl_multi_remove_handle()
743 if(multi->in_callback) in curl_multi_remove_handle()
755 multi->num_alive--; in curl_multi_remove_handle()
783 /* The timer must be shut down before data->multi is set to NULL, else the in curl_multi_remove_handle()
791 Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); in curl_multi_remove_handle()
794 /* stop using the multi handle's DNS cache, *after* the possible in curl_multi_remove_handle()
809 singlesocket(multi, easy); /* to let the application know what sockets that in curl_multi_remove_handle()
823 if(data->psl == &multi->psl) in curl_multi_remove_handle()
828 since we're not part of that multi handle anymore */ in curl_multi_remove_handle()
831 data->multi = NULL; /* clear the association to this multi handle */ in curl_multi_remove_handle()
836 for(e = multi->msglist.head; e; e = e->next) { in curl_multi_remove_handle()
840 Curl_llist_remove(&multi->msglist, e, NULL); in curl_multi_remove_handle()
850 multi->easyp = data->next; /* point to first node */ in curl_multi_remove_handle()
856 multi->easylp = data->prev; /* point to last node */ in curl_multi_remove_handle()
860 multi->num_easy--; /* one less to care about now */ in curl_multi_remove_handle()
862 Curl_update_timer(multi); in curl_multi_remove_handle()
867 bool Curl_multiplex_wanted(const struct Curl_multi *multi) in Curl_multiplex_wanted() argument
869 return (multi && (multi->multiplexing)); in Curl_multiplex_wanted()
1025 CURLMcode curl_multi_fdset(struct Curl_multi *multi, in curl_multi_fdset() argument
1038 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_fdset()
1041 if(multi->in_callback) in curl_multi_fdset()
1044 data = multi->easyp; in curl_multi_fdset()
1076 static CURLMcode Curl_multi_wait(struct Curl_multi *multi, argument
1099 DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
1102 if(!GOOD_MULTI_HANDLE(multi))
1105 if(multi->in_callback)
1111 /* Count up how many fds we have from the multi handle */
1112 data = multi->easyp;
1138 (void)multi_timeout(multi, &timeout_internal);
1149 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1175 data = multi->easyp;
1212 if(WSAEventSelect(s, multi->wsa_event, mask) != 0)
1251 if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0)
1268 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1269 ufds[nfds].fd = multi->wakeup_pair[0];
1279 WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
1301 if(WSAEnumNetworkEvents(extra_fds[i].fd, multi->wsa_event,
1312 WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
1330 data = multi->easyp;
1337 if(WSAEnumNetworkEvents(sockbunch[i], multi->wsa_event,
1350 WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
1360 WSAResetEvent(multi->wsa_event);
1363 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1372 nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
1401 if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
1404 /* when there are no easy handles in the multi, this holds a -1
1415 CURLMcode curl_multi_wait(struct Curl_multi *multi, argument
1421 return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
1425 CURLMcode curl_multi_poll(struct Curl_multi *multi, argument
1431 return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
1435 CURLMcode curl_multi_wakeup(struct Curl_multi *multi) argument
1442 if(!GOOD_MULTI_HANDLE(multi))
1447 if(WSASetEvent(multi->wsa_event))
1453 if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
1466 if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1495 static bool multi_ischanged(struct Curl_multi *multi, bool clear) argument
1497 bool retval = multi->recheckstate;
1499 multi->recheckstate = FALSE;
1503 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, argument
1509 if(multi->in_callback)
1512 rc = curl_multi_add_handle(multi, data);
1561 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1587 * over from the multi interface until the connection phase is done on
1607 * We are DOING this is being called over and over from the multi interface
1703 static CURLMcode multi_runsingle(struct Curl_multi *multi, argument
1729 if(multi_ischanged(multi, TRUE)) {
1730 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
1731 process_pending_handles(multi); /* multiplexed */
1828 Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
1836 process_pending_handles(data->multi);
1902 singlesocket(multi, data);
2197 process_pending_handles(multi); /* multiplexed */
2417 process_pending_handles(multi); /* multiplexing */
2473 process_pending_handles(multi); /* connection */
2528 rc = multi_addmsg(multi, msg);
2533 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2540 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) argument
2547 if(!GOOD_MULTI_HANDLE(multi))
2550 if(multi->in_callback)
2553 data = multi->easyp;
2559 result = multi_runsingle(multi, &now, data);
2579 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2582 (void)add_next_timeout(now, multi, t->payload);
2586 *running_handles = multi->num_alive;
2589 Curl_update_timer(multi);
2594 CURLMcode curl_multi_cleanup(struct Curl_multi *multi) argument
2599 if(GOOD_MULTI_HANDLE(multi)) {
2600 if(multi->in_callback)
2603 multi->type = 0; /* not good anymore */
2606 data = multi->easyp;
2621 data->multi = NULL; /* clear the association */
2624 if(data->psl == &multi->psl)
2632 Curl_conncache_close_all_connections(&multi->conn_cache);
2634 Curl_hash_destroy(&multi->sockhash);
2635 Curl_conncache_destroy(&multi->conn_cache);
2636 Curl_llist_destroy(&multi->msglist, NULL);
2637 Curl_llist_destroy(&multi->pending, NULL);
2639 Curl_hash_destroy(&multi->hostcache);
2640 Curl_psl_destroy(&multi->psl);
2643 WSACloseEvent(multi->wsa_event);
2646 sclose(multi->wakeup_pair[0]);
2647 sclose(multi->wakeup_pair[1]);
2650 free(multi);
2660 * This function is the primary way for a multi/multi_socket application to
2667 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) argument
2673 if(GOOD_MULTI_HANDLE(multi) &&
2674 !multi->in_callback &&
2675 Curl_llist_count(&multi->msglist)) {
2680 e = multi->msglist.head;
2685 Curl_llist_remove(&multi->msglist, e, NULL);
2687 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
2699 static CURLMcode singlesocket(struct Curl_multi *multi, argument
2733 entry = sh_getentry(&multi->sockhash, s);
2754 entry = sh_addentry(&multi->sockhash, s);
2792 if(multi->socket_cb)
2793 multi->socket_cb(data, s, comboaction, multi->socket_userp,
2817 entry = sh_getentry(&multi->sockhash, s);
2829 if(multi->socket_cb)
2830 multi->socket_cb(data, s, CURL_POLL_REMOVE,
2831 multi->socket_userp,
2833 sh_delentry(entry, &multi->sockhash, s);
2853 singlesocket(data->multi, data);
2871 struct Curl_multi *multi = data->multi; local
2872 if(multi) {
2874 a multi handle, and only then this is necessary */
2875 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2878 if(multi->socket_cb)
2879 multi->socket_cb(data, s, CURL_POLL_REMOVE,
2880 multi->socket_userp,
2884 sh_delentry(entry, &multi->sockhash, s);
2903 struct Curl_multi *multi, argument
2940 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2946 static CURLMcode multi_socket(struct Curl_multi *multi, argument
2959 result = curl_multi_perform(multi, running_handles);
2964 data = multi->easyp;
2966 result = singlesocket(multi, data);
2975 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3019 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
3033 result = multi_runsingle(multi, &now, data);
3039 result = singlesocket(multi, data);
3048 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3051 (void)add_next_timeout(now, multi, t->payload);
3056 *running_handles = multi->num_alive;
3061 CURLMcode curl_multi_setopt(struct Curl_multi *multi, argument
3067 if(!GOOD_MULTI_HANDLE(multi))
3070 if(multi->in_callback)
3077 multi->socket_cb = va_arg(param, curl_socket_callback);
3080 multi->socket_userp = va_arg(param, void *);
3083 multi->push_cb = va_arg(param, curl_push_callback);
3086 multi->push_userp = va_arg(param, void *);
3089 multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX;
3092 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3095 multi->timer_userp = va_arg(param, void *);
3098 multi->maxconnects = va_arg(param, long);
3101 multi->max_host_connections = va_arg(param, long);
3104 multi->max_total_connections = va_arg(param, long);
3122 multi->max_concurrent_streams = curlx_sltoui(streams);
3133 /* we define curl_multi_socket() in the public multi.h header */
3136 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, argument
3140 if(multi->in_callback)
3142 result = multi_socket(multi, FALSE, s, 0, running_handles);
3144 Curl_update_timer(multi);
3148 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, argument
3152 if(multi->in_callback)
3154 result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3156 Curl_update_timer(multi);
3160 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) argument
3164 if(multi->in_callback)
3166 result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3168 Curl_update_timer(multi);
3172 static CURLMcode multi_timeout(struct Curl_multi *multi, argument
3177 if(multi->timetree) {
3182 multi->timetree = Curl_splay(tv_zero, multi->timetree);
3184 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
3186 timediff_t diff = Curl_timediff(multi->timetree->key, now);
3211 CURLMcode curl_multi_timeout(struct Curl_multi *multi, argument
3215 if(!GOOD_MULTI_HANDLE(multi))
3218 if(multi->in_callback)
3221 return multi_timeout(multi, timeout_ms);
3228 void Curl_update_timer(struct Curl_multi *multi) argument
3232 if(!multi->timer_cb)
3234 if(multi_timeout(multi, &timeout_ms)) {
3239 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
3240 multi->timer_lastcall = none;
3243 multi->timer_cb(multi, -1, multi->timer_userp);
3249 /* When multi_timeout() is done, multi->timetree points to the node with the
3253 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
3256 multi->timer_lastcall = multi->timetree->key;
3258 multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3337 struct Curl_multi *multi = data->multi; local
3341 /* this is only interesting while there is still an associated multi struct
3343 if(!multi)
3379 rc = Curl_splayremovebyaddr(multi->timetree,
3381 &multi->timetree);
3390 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
3413 struct Curl_multi *multi = data->multi; local
3416 /* this is only interesting while there is still an associated multi struct
3418 if(!multi)
3427 rc = Curl_splayremovebyaddr(multi->timetree,
3429 &multi->timetree);
3449 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, argument
3454 if(multi->in_callback)
3457 there = sh_getentry(&multi->sockhash, s);
3467 size_t Curl_multi_max_host_connections(struct Curl_multi *multi) argument
3469 return multi ? multi->max_host_connections : 0;
3472 size_t Curl_multi_max_total_connections(struct Curl_multi *multi) argument
3474 return multi ? multi->max_total_connections : 0;
3487 DEBUGASSERT(conn->data->multi);
3490 process_pending_handles(conn->data->multi);
3493 static void process_pending_handles(struct Curl_multi *multi) argument
3495 struct Curl_llist_element *e = multi->pending.head;
3504 Curl_llist_remove(&multi->pending, e, NULL);
3520 else if(data->multi)
3521 data->multi->in_callback = value;
3527 return ((easy->multi && easy->multi->in_callback) ||
3532 void Curl_multi_dump(struct Curl_multi *multi) argument
3536 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
3537 multi->num_easy, multi->num_alive);
3538 for(data = multi->easyp; data; data = data->next) {
3546 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3564 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi) argument
3566 DEBUGASSERT(multi);
3567 return multi->max_concurrent_streams;