Lines Matching refs:multi
90 static void move_pending_to_connect(struct Curl_multi *multi,
92 static CURLMcode singlesocket(struct Curl_multi *multi,
95 struct Curl_multi *multi,
97 static CURLMcode multi_timeout(struct Curl_multi *multi,
100 static void process_pending_handles(struct Curl_multi *multi);
101 static void multi_xfer_bufs_free(struct Curl_multi *multi);
199 DEBUGASSERT(data->multi->num_alive > 0); in mstate()
200 data->multi->num_alive--; in mstate()
201 if(!data->multi->num_alive) { in mstate()
203 multi_xfer_bufs_free(data->multi); in mstate()
393 static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg) in multi_addmsg() argument
395 Curl_llist_append(&multi->msglist, msg, &msg->list); in multi_addmsg()
402 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); in Curl_multi_handle() local
404 if(!multi) in Curl_multi_handle()
407 multi->magic = CURL_MULTI_HANDLE; in Curl_multi_handle()
409 Curl_init_dnscache(&multi->hostcache, dnssize); in Curl_multi_handle()
411 sh_init(&multi->sockhash, hashsize); in Curl_multi_handle()
413 Curl_hash_init(&multi->proto_hash, 23, in Curl_multi_handle()
416 if(Curl_cpool_init(&multi->cpool, Curl_on_disconnect, in Curl_multi_handle()
417 multi, NULL, chashsize)) in Curl_multi_handle()
420 Curl_llist_init(&multi->msglist, NULL); in Curl_multi_handle()
421 Curl_llist_init(&multi->process, NULL); in Curl_multi_handle()
422 Curl_llist_init(&multi->pending, NULL); in Curl_multi_handle()
423 Curl_llist_init(&multi->msgsent, NULL); in Curl_multi_handle()
425 multi->multiplexing = TRUE; in Curl_multi_handle()
426 multi->max_concurrent_streams = 100; in Curl_multi_handle()
427 multi->last_timeout_ms = -1; in Curl_multi_handle()
430 multi->wsa_event = WSACreateEvent(); in Curl_multi_handle()
431 if(multi->wsa_event == WSA_INVALID_EVENT) in Curl_multi_handle()
435 if(wakeup_create(multi->wakeup_pair, TRUE) < 0) { in Curl_multi_handle()
436 multi->wakeup_pair[0] = CURL_SOCKET_BAD; in Curl_multi_handle()
437 multi->wakeup_pair[1] = CURL_SOCKET_BAD; in Curl_multi_handle()
442 return multi; in Curl_multi_handle()
446 sockhash_destroy(&multi->sockhash); in Curl_multi_handle()
447 Curl_hash_destroy(&multi->proto_hash); in Curl_multi_handle()
448 Curl_hash_destroy(&multi->hostcache); in Curl_multi_handle()
449 Curl_cpool_destroy(&multi->cpool); in Curl_multi_handle()
450 free(multi); in Curl_multi_handle()
462 static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data) in multi_warn_debug() argument
464 if(!multi->warned) { in multi_warn_debug()
468 multi->warned = TRUE; in multi_warn_debug()
478 struct Curl_multi *multi = m; in curl_multi_add_handle() local
481 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_add_handle()
490 if(data->multi) in curl_multi_add_handle()
493 if(multi->in_callback) in curl_multi_add_handle()
496 if(multi->dead) { in curl_multi_add_handle()
500 if(multi->num_alive) in curl_multi_add_handle()
502 multi->dead = FALSE; in curl_multi_add_handle()
528 data->multi = multi; in curl_multi_add_handle()
538 rc = Curl_update_timer(multi); in curl_multi_add_handle()
540 data->multi = NULL; /* not anymore */ in curl_multi_add_handle()
551 data->dns.hostcache = &multi->hostcache; in curl_multi_add_handle()
560 data->psl = &multi->psl; in curl_multi_add_handle()
564 Curl_llist_append(&multi->process, data, &data->multi_queue); in curl_multi_add_handle()
567 multi->num_easy++; in curl_multi_add_handle()
570 multi->num_alive++; in curl_multi_add_handle()
573 data->mid = multi->next_easy_mid++; in curl_multi_add_handle()
574 if(multi->next_easy_mid <= 0) in curl_multi_add_handle()
575 multi->next_easy_mid = 0; in curl_multi_add_handle()
578 multi_warn_debug(multi, data); in curl_multi_add_handle()
751 process_pending_handles(data->multi); /* connection / multiplex */ in multi_done()
778 struct Curl_multi *multi = m; in curl_multi_remove_handle() local
786 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_remove_handle()
790 if(!GOOD_EASY_HANDLE(data) || !multi->num_easy) in curl_multi_remove_handle()
794 if(!data->multi) in curl_multi_remove_handle()
798 if(data->multi != multi) in curl_multi_remove_handle()
801 if(multi->in_callback) in curl_multi_remove_handle()
811 multi->num_alive--; in curl_multi_remove_handle()
854 (void)singlesocket(multi, data); /* to let the application know what sockets in curl_multi_remove_handle()
885 if(data->psl == &multi->psl) in curl_multi_remove_handle()
891 for(e = Curl_llist_head(&multi->msglist); e; e = Curl_node_next(e)) { in curl_multi_remove_handle()
901 data->multi = NULL; /* clear the association to this multi handle */ in curl_multi_remove_handle()
906 multi->num_easy--; /* one less to care about now */ in curl_multi_remove_handle()
907 process_pending_handles(multi); in curl_multi_remove_handle()
910 rc = Curl_update_timer(multi); in curl_multi_remove_handle()
918 bool Curl_multiplex_wanted(const struct Curl_multi *multi) in Curl_multiplex_wanted() argument
920 return (multi && (multi->multiplexing)); in Curl_multiplex_wanted()
1154 struct Curl_multi *multi = m; in curl_multi_fdset() local
1157 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_fdset()
1160 if(multi->in_callback) in curl_multi_fdset()
1163 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { in curl_multi_fdset()
1195 struct Curl_multi *multi = m; in curl_multi_waitfds() local
1200 if(!GOOD_MULTI_HANDLE(multi)) in curl_multi_waitfds()
1203 if(multi->in_callback) in curl_multi_waitfds()
1207 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { in curl_multi_waitfds()
1216 if(Curl_cpool_add_waitfds(&multi->cpool, &cwfds)) { in curl_multi_waitfds()
1245 static CURLMcode multi_wait(struct Curl_multi *multi, argument
1265 DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
1271 if(!GOOD_MULTI_HANDLE(multi))
1274 if(multi->in_callback)
1283 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
1293 if(Curl_cpool_add_pollfds(&multi->cpool, &cpfds)) {
1327 if(WSAEventSelect(cpfds.pfds[i].fd, multi->wsa_event, mask) != 0) {
1337 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1338 if(Curl_pollfds_add_sock(&cpfds, multi->wakeup_pair[0], POLLIN)) {
1350 (void)multi_timeout(multi, &expire_time, &timeout_internal);
1378 WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, (DWORD)timeout_ms,
1404 WSAEventSelect(s, multi->wsa_event, 0);
1423 for(e = Curl_llist_head(&multi->process); e && !result;
1434 WSAEventSelect(data->last_poll.sockets[i], multi->wsa_event, 0);
1439 WSAResetEvent(multi->wsa_event);
1442 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1451 nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf));
1477 if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
1493 CURLMcode curl_multi_wait(CURLM *multi, argument
1499 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
1503 CURLMcode curl_multi_poll(CURLM *multi, argument
1509 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
1518 struct Curl_multi *multi = m; local
1530 if(!GOOD_MULTI_HANDLE(multi))
1535 if(WSASetEvent(multi->wsa_event))
1541 if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
1560 if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1589 static bool multi_ischanged(struct Curl_multi *multi, bool clear) argument
1591 bool retval = multi->recheckstate;
1593 multi->recheckstate = FALSE;
1604 void Curl_multi_connchanged(struct Curl_multi *multi) argument
1606 multi->recheckstate = TRUE;
1609 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, argument
1615 if(multi->in_callback)
1618 rc = curl_multi_add_handle(multi, data);
1811 static void set_in_callback(struct Curl_multi *multi, bool value) argument
1813 multi->in_callback = value;
2467 static CURLMcode state_resolving(struct Curl_multi *multi, argument
2509 rc = singlesocket(multi, data);
2542 static CURLMcode state_connect(struct Curl_multi *multi, argument
2560 Curl_llist_append(&multi->pending, data, &data->multi_queue);
2565 process_pending_handles(data->multi);
2582 process_pending_handles(data->multi);
2595 static CURLMcode multi_runsingle(struct Curl_multi *multi, argument
2610 if(multi->dead) {
2619 multi_warn_debug(multi, data);
2627 if(multi_ischanged(multi, TRUE)) {
2629 process_pending_handles(multi); /* multiplexed */
2676 rc = state_connect(multi, data, nowp, &result);
2681 rc = state_resolving(multi, data, &stream_error, &result);
2707 process_pending_handles(data->multi);
2821 process_pending_handles(multi); /* multiplexed */
2894 !multi_ischanged(multi, FALSE)) {
2917 process_pending_handles(multi); /* connection */
2968 multi_addmsg(multi, msg);
2976 Curl_llist_append(&multi->msgsent, data, &data->multi_queue);
2979 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2993 struct Curl_multi *multi = m; local
2996 if(!GOOD_MULTI_HANDLE(multi))
2999 if(multi->in_callback)
3003 for(e = Curl_llist_head(&multi->process); e; e = n) {
3013 if(data != multi->cpool.idata) {
3016 result = multi_runsingle(multi, &now, data);
3022 sigpipe_apply(multi->cpool.idata, &pipe_st);
3023 Curl_cpool_multi_perform(multi);
3038 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3047 move_pending_to_connect(multi, data);
3050 (void)add_next_timeout(now, multi, Curl_splayget(t));
3055 *running_handles = (int)multi->num_alive;
3058 returncode = Curl_update_timer(multi);
3065 static void unlink_all_msgsent_handles(struct Curl_multi *multi) argument
3068 for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) {
3074 Curl_llist_append(&multi->process, data, &data->multi_queue);
3081 struct Curl_multi *multi = m; local
3082 if(GOOD_MULTI_HANDLE(multi)) {
3085 if(multi->in_callback)
3090 unlink_all_msgsent_handles(multi);
3091 process_pending_handles(multi);
3094 for(e = Curl_llist_head(&multi->process); e; e = n) {
3111 data->multi = NULL; /* clear the association */
3114 if(data->psl == &multi->psl)
3119 Curl_cpool_destroy(&multi->cpool);
3121 multi->magic = 0; /* not good anymore */
3123 sockhash_destroy(&multi->sockhash);
3124 Curl_hash_destroy(&multi->proto_hash);
3125 Curl_hash_destroy(&multi->hostcache);
3126 Curl_psl_destroy(&multi->psl);
3129 WSACloseEvent(multi->wsa_event);
3132 wakeup_close(multi->wakeup_pair[0]);
3134 wakeup_close(multi->wakeup_pair[1]);
3139 multi_xfer_bufs_free(multi);
3140 free(multi);
3160 struct Curl_multi *multi = m; local
3164 if(GOOD_MULTI_HANDLE(multi) &&
3165 !multi->in_callback &&
3166 Curl_llist_count(&multi->msglist)) {
3171 e = Curl_llist_head(&multi->msglist);
3178 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
3190 static CURLMcode singlesocket(struct Curl_multi *multi, argument
3199 mresult = Curl_multi_pollset_ev(multi, data, &cur_poll, &data->last_poll);
3206 CURLMcode Curl_multi_pollset_ev(struct Curl_multi *multi, argument
3229 entry = sh_getentry(&multi->sockhash, s);
3242 entry = sh_addentry(&multi->sockhash, s);
3289 if(multi->socket_cb) {
3290 set_in_callback(multi, TRUE);
3291 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
3294 set_in_callback(multi, FALSE);
3296 multi->dead = TRUE;
3322 entry = sh_getentry(&multi->sockhash, s);
3336 if(multi->socket_cb) {
3337 set_in_callback(multi, TRUE);
3338 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3339 multi->socket_userp, entry->socketp);
3340 set_in_callback(multi, FALSE);
3344 sh_delentry(entry, &multi->sockhash, s);
3346 multi->dead = TRUE;
3365 if(singlesocket(data->multi, data))
3385 struct Curl_multi *multi = data->multi; local
3387 " multi is %p", s, (void *)multi));
3388 if(multi) {
3391 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3397 if(multi->socket_cb) {
3398 set_in_callback(multi, TRUE);
3399 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3400 multi->socket_userp, entry->socketp);
3401 set_in_callback(multi, FALSE);
3405 sh_delentry(entry, &multi->sockhash, s);
3410 multi->dead = TRUE;
3429 struct Curl_multi *multi, argument
3465 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
3472 struct Curl_multi *multi; member
3481 struct Curl_multi *multi = mrc->multi; local
3494 multi->timetree = Curl_splaygetbest(mrc->now, multi->timetree, &t);
3502 (void)add_next_timeout(mrc->now, multi, data);
3503 if(data == multi->cpool.idata) {
3510 result = multi_runsingle(multi, &mrc->now, data);
3515 result = singlesocket(multi, data);
3524 static CURLMcode multi_socket(struct Curl_multi *multi, argument
3536 mrc.multi = multi;
3543 result = curl_multi_perform(multi, running_handles);
3548 for(e = Curl_llist_head(&multi->process); e && !result;
3550 result = singlesocket(multi, Curl_node_elem(e));
3558 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3568 Curl_cpool_multi_socket(multi, s, ev_bitmask);
3582 if(data == multi->cpool.idata)
3609 sigpipe_apply(multi->cpool.idata, &mrc.pipe_st);
3610 Curl_cpool_multi_perform(multi);
3615 *running_handles = (int)multi->num_alive;
3618 result = Curl_update_timer(multi);
3629 struct Curl_multi *multi = m; local
3631 if(!GOOD_MULTI_HANDLE(multi))
3634 if(multi->in_callback)
3641 multi->socket_cb = va_arg(param, curl_socket_callback);
3644 multi->socket_userp = va_arg(param, void *);
3647 multi->push_cb = va_arg(param, curl_push_callback);
3650 multi->push_userp = va_arg(param, void *);
3653 multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0;
3656 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3659 multi->timer_userp = va_arg(param, void *);
3664 multi->maxconnects = (unsigned int)uarg;
3667 multi->max_host_connections = va_arg(param, long);
3670 multi->max_total_connections = va_arg(param, long);
3673 multi->max_shutdown_connections = va_arg(param, long);
3691 multi->max_concurrent_streams = (unsigned int)streams;
3707 struct Curl_multi *multi = m; local
3708 if(multi->in_callback)
3710 return multi_socket(multi, FALSE, s, 0, running_handles);
3716 struct Curl_multi *multi = m; local
3717 if(multi->in_callback)
3719 return multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3724 struct Curl_multi *multi = m; local
3725 if(multi->in_callback)
3727 return multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3730 static CURLMcode multi_timeout(struct Curl_multi *multi, argument
3736 if(multi->dead) {
3741 if(multi->timetree) {
3746 multi->timetree = Curl_splay(tv_zero, multi->timetree);
3749 *expire_time = multi->timetree ? multi->timetree->key : tv_zero;
3753 if(multi->timetree &&
3754 Curl_timediff_us(multi->timetree->key, now) > 0) {
3756 timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now);
3778 struct Curl_multi *multi = m; local
3781 if(!GOOD_MULTI_HANDLE(multi))
3784 if(multi->in_callback)
3787 return multi_timeout(multi, &expire_time, timeout_ms);
3796 CURLMcode Curl_update_timer(struct Curl_multi *multi) argument
3803 if(!multi->timer_cb || multi->dead)
3805 if(multi_timeout(multi, &expire_ts, &timeout_ms)) {
3809 if(timeout_ms < 0 && multi->last_timeout_ms < 0) {
3818 " last_timeout=%ldms\n", multi->last_timeout_ms);
3823 else if(multi->last_timeout_ms < 0) {
3829 else if(Curl_timediff_us(multi->last_expire_ts, expire_ts)) {
3851 multi->last_expire_ts = expire_ts;
3852 multi->last_timeout_ms = timeout_ms;
3853 set_in_callback(multi, TRUE);
3854 rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3855 set_in_callback(multi, FALSE);
3857 multi->dead = TRUE;
3931 struct Curl_multi *multi = data->multi; local
3937 if(!multi)
3973 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3974 &multi->timetree);
3983 multi->timetree = Curl_splayinsert(*curr_expire, multi->timetree,
4023 struct Curl_multi *multi = data->multi; local
4028 if(!multi)
4037 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
4038 &multi->timetree);
4059 struct Curl_multi *multi = m; local
4060 if(!GOOD_MULTI_HANDLE(multi))
4063 there = sh_getentry(&multi->sockhash, s);
4073 static void move_pending_to_connect(struct Curl_multi *multi, argument
4082 Curl_llist_append(&multi->process, data, &data->multi_queue);
4104 static void process_pending_handles(struct Curl_multi *multi) argument
4106 struct Curl_llist_node *e = Curl_llist_head(&multi->pending);
4109 move_pending_to_connect(multi, data);
4115 if(data && data->multi)
4116 data->multi->in_callback = value;
4121 return (data && data->multi && data->multi->in_callback);
4124 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi) argument
4126 DEBUGASSERT(multi);
4127 return multi->max_concurrent_streams;
4132 struct Curl_multi *multi = m; local
4133 CURL **a = malloc(sizeof(struct Curl_easy *) * (multi->num_easy + 1));
4137 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
4139 DEBUGASSERT(i < multi->num_easy);
4152 DEBUGASSERT(data->multi);
4155 if(!data->multi) {
4163 if(data->multi->xfer_buf_borrowed) {
4168 if(data->multi->xfer_buf &&
4169 data->set.buffer_size > data->multi->xfer_buf_len) {
4171 free(data->multi->xfer_buf);
4172 data->multi->xfer_buf = NULL;
4173 data->multi->xfer_buf_len = 0;
4176 if(!data->multi->xfer_buf) {
4177 data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
4178 if(!data->multi->xfer_buf) {
4183 data->multi->xfer_buf_len = data->set.buffer_size;
4186 data->multi->xfer_buf_borrowed = TRUE;
4187 *pbuf = data->multi->xfer_buf;
4188 *pbuflen = data->multi->xfer_buf_len;
4196 DEBUGASSERT(data->multi);
4197 DEBUGASSERT(!buf || data->multi->xfer_buf == buf);
4198 data->multi->xfer_buf_borrowed = FALSE;
4205 DEBUGASSERT(data->multi);
4208 if(!data->multi) {
4216 if(data->multi->xfer_ulbuf_borrowed) {
4221 if(data->multi->xfer_ulbuf &&
4222 data->set.upload_buffer_size > data->multi->xfer_ulbuf_len) {
4224 free(data->multi->xfer_ulbuf);
4225 data->multi->xfer_ulbuf = NULL;
4226 data->multi->xfer_ulbuf_len = 0;
4229 if(!data->multi->xfer_ulbuf) {
4230 data->multi->xfer_ulbuf = malloc((size_t)data->set.upload_buffer_size);
4231 if(!data->multi->xfer_ulbuf) {
4236 data->multi->xfer_ulbuf_len = data->set.upload_buffer_size;
4239 data->multi->xfer_ulbuf_borrowed = TRUE;
4240 *pbuf = data->multi->xfer_ulbuf;
4241 *pbuflen = data->multi->xfer_ulbuf_len;
4249 DEBUGASSERT(data->multi);
4250 DEBUGASSERT(!buf || data->multi->xfer_ulbuf == buf);
4251 data->multi->xfer_ulbuf_borrowed = FALSE;
4258 DEBUGASSERT(data->multi);
4260 if(!data->multi) {
4264 if(data->multi->xfer_sockbuf_borrowed) {
4269 if(data->multi->xfer_sockbuf && blen > data->multi->xfer_sockbuf_len) {
4271 free(data->multi->xfer_sockbuf);
4272 data->multi->xfer_sockbuf = NULL;
4273 data->multi->xfer_sockbuf_len = 0;
4276 if(!data->multi->xfer_sockbuf) {
4277 data->multi->xfer_sockbuf = malloc(blen);
4278 if(!data->multi->xfer_sockbuf) {
4282 data->multi->xfer_sockbuf_len = blen;
4285 data->multi->xfer_sockbuf_borrowed = TRUE;
4286 *pbuf = data->multi->xfer_sockbuf;
4294 DEBUGASSERT(data->multi);
4295 DEBUGASSERT(!buf || data->multi->xfer_sockbuf == buf);
4296 data->multi->xfer_sockbuf_borrowed = FALSE;
4299 static void multi_xfer_bufs_free(struct Curl_multi *multi) argument
4301 DEBUGASSERT(multi);
4302 Curl_safefree(multi->xfer_buf);
4303 multi->xfer_buf_len = 0;
4304 multi->xfer_buf_borrowed = FALSE;
4305 Curl_safefree(multi->xfer_ulbuf);
4306 multi->xfer_ulbuf_len = 0;
4307 multi->xfer_ulbuf_borrowed = FALSE;
4308 Curl_safefree(multi->xfer_sockbuf);
4309 multi->xfer_sockbuf_len = 0;
4310 multi->xfer_sockbuf_borrowed = FALSE;
4313 struct Curl_easy *Curl_multi_get_handle(struct Curl_multi *multi, argument
4321 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
4327 for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) {
4333 for(e = Curl_llist_head(&multi->pending); e; e = Curl_node_next(e)) {