Lines Matching full:multi
79 /* On a debug build, we want to fail hard on multi handles that
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()
376 /* multi->proto_hash destructor. Should never be called as elements
391 * the list kept in the multi handle.
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()
489 adding to more than one multi stack */ 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()
507 is a private multi handle here that we can kill */ in curl_multi_add_handle()
517 * easy nor multi handle allowed before this except for potential multi's in curl_multi_add_handle()
526 /* make the Curl_easy refer back to this multi handle - before Curl_expire() 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()
547 /* for multi interface connections, we share DNS cache automatically if the 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()
572 /* the identifier inside the multi instance */ 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()
586 * Curl_hash_print(&multi->sockhash, debug_print_sock_hash);
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()
797 /* Prevent users from trying to remove an easy handle from the wrong 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()
831 /* The timer must be shut down before data->multi is set to NULL, else the in curl_multi_remove_handle()
840 /* stop using the multi handle's DNS cache, *after* the possible in curl_multi_remove_handle()
854 (void)singlesocket(multi, data); /* to let the application know what sockets in curl_multi_remove_handle()
861 /* This removes a handle that was part the multi interface that used in curl_multi_remove_handle()
865 anymore once removed from the multi handle 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()
1126 failf(data, "multi_getsock: unexpected multi state %d", data->mstate); in multi_getsock()
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) {
1480 /* when there are no easy handles in the multi, this holds a -1
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) {
1557 if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1586 static bool multi_ischanged(struct Curl_multi *multi, bool clear) argument
1588 bool retval = multi->recheckstate;
1590 multi->recheckstate = FALSE;
1596 * this multi handle that has changed state (multiplexing become possible, the
1598 * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1601 void Curl_multi_connchanged(struct Curl_multi *multi) argument
1603 multi->recheckstate = TRUE;
1606 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, argument
1612 if(multi->in_callback)
1615 rc = curl_multi_add_handle(multi, data);
1646 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1721 * over from the multi interface until the connection phase is done on
1741 * We are DOING this is being called over and over from the multi interface
1808 static void set_in_callback(struct Curl_multi *multi, bool value) argument
1810 multi->in_callback = value;
2464 static CURLMcode state_resolving(struct Curl_multi *multi, argument
2506 rc = singlesocket(multi, data);
2539 static CURLMcode state_connect(struct Curl_multi *multi, argument
2557 Curl_llist_append(&multi->pending, data, &data->multi_queue);
2562 process_pending_handles(data->multi);
2579 process_pending_handles(data->multi);
2592 static CURLMcode multi_runsingle(struct Curl_multi *multi, argument
2607 if(multi->dead) {
2608 /* a multi-level callback returned error before, meaning every individual
2616 multi_warn_debug(multi, data);
2624 if(multi_ischanged(multi, TRUE)) {
2625 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
2626 process_pending_handles(multi); /* multiplexed */
2673 rc = state_connect(multi, data, nowp, &result);
2678 rc = state_resolving(multi, data, &stream_error, &result);
2704 process_pending_handles(data->multi);
2818 process_pending_handles(multi); /* multiplexed */
2891 !multi_ischanged(multi, FALSE)) {
2914 process_pending_handles(multi); /* connection */
2965 multi_addmsg(multi, msg);
2973 Curl_llist_append(&multi->msgsent, data, &data->multi_queue);
2976 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2990 struct Curl_multi *multi = m; local
2993 if(!GOOD_MULTI_HANDLE(multi))
2996 if(multi->in_callback)
3000 for(e = Curl_llist_head(&multi->process); e; e = n) {
3010 if(data != multi->cpool.idata) {
3013 result = multi_runsingle(multi, &now, data);
3019 sigpipe_apply(multi->cpool.idata, &pipe_st);
3020 Curl_cpool_multi_perform(multi);
3035 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3044 move_pending_to_connect(multi, data);
3047 (void)add_next_timeout(now, multi, Curl_splayget(t));
3052 *running_handles = (int)multi->num_alive;
3055 returncode = Curl_update_timer(multi);
3062 static void unlink_all_msgsent_handles(struct Curl_multi *multi) argument
3065 for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) {
3071 Curl_llist_append(&multi->process, data, &data->multi_queue);
3078 struct Curl_multi *multi = m; local
3079 if(GOOD_MULTI_HANDLE(multi)) {
3082 if(multi->in_callback)
3087 unlink_all_msgsent_handles(multi);
3088 process_pending_handles(multi);
3091 for(e = Curl_llist_head(&multi->process); e; e = n) {
3108 data->multi = NULL; /* clear the association */
3111 if(data->psl == &multi->psl)
3116 Curl_cpool_destroy(&multi->cpool);
3118 multi->magic = 0; /* not good anymore */
3120 sockhash_destroy(&multi->sockhash);
3121 Curl_hash_destroy(&multi->proto_hash);
3122 Curl_hash_destroy(&multi->hostcache);
3123 Curl_psl_destroy(&multi->psl);
3126 WSACloseEvent(multi->wsa_event);
3129 wakeup_close(multi->wakeup_pair[0]);
3131 wakeup_close(multi->wakeup_pair[1]);
3136 multi_xfer_bufs_free(multi);
3137 free(multi);
3147 * This function is the primary way for a multi/multi_socket application to
3157 struct Curl_multi *multi = m; local
3161 if(GOOD_MULTI_HANDLE(multi) &&
3162 !multi->in_callback &&
3163 Curl_llist_count(&multi->msglist)) {
3168 e = Curl_llist_head(&multi->msglist);
3175 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
3187 static CURLMcode singlesocket(struct Curl_multi *multi, argument
3196 mresult = Curl_multi_pollset_ev(multi, data, &cur_poll, &data->last_poll);
3203 CURLMcode Curl_multi_pollset_ev(struct Curl_multi *multi, argument
3226 entry = sh_getentry(&multi->sockhash, s);
3239 entry = sh_addentry(&multi->sockhash, s);
3286 if(multi->socket_cb) {
3287 set_in_callback(multi, TRUE);
3288 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
3291 set_in_callback(multi, FALSE);
3293 multi->dead = TRUE;
3303 * Need to remove the easy handle from the multi->sockhash->transfers and
3304 * remove multi->sockhash entry when this was the last transfer */
3319 entry = sh_getentry(&multi->sockhash, s);
3333 if(multi->socket_cb) {
3334 set_in_callback(multi, TRUE);
3335 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3336 multi->socket_userp, entry->socketp);
3337 set_in_callback(multi, FALSE);
3341 sh_delentry(entry, &multi->sockhash, s);
3343 multi->dead = TRUE;
3362 if(singlesocket(data->multi, data))
3382 struct Curl_multi *multi = data->multi; local
3384 " multi is %p", s, (void *)multi));
3385 if(multi) {
3387 a multi handle, and only then this is necessary */
3388 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3394 if(multi->socket_cb) {
3395 set_in_callback(multi, TRUE);
3396 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3397 multi->socket_userp, entry->socketp);
3398 set_in_callback(multi, FALSE);
3402 sh_delentry(entry, &multi->sockhash, s);
3404 /* This just marks the multi handle as "dead" without returning an
3407 multi->dead = TRUE;
3426 struct Curl_multi *multi, argument
3462 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
3469 struct Curl_multi *multi; member
3478 struct Curl_multi *multi = mrc->multi; local
3491 multi->timetree = Curl_splaygetbest(mrc->now, multi->timetree, &t);
3499 (void)add_next_timeout(mrc->now, multi, data);
3500 if(data == multi->cpool.idata) {
3507 result = multi_runsingle(multi, &mrc->now, data);
3512 result = singlesocket(multi, data);
3521 static CURLMcode multi_socket(struct Curl_multi *multi, argument
3533 mrc.multi = multi;
3540 result = curl_multi_perform(multi, running_handles);
3545 for(e = Curl_llist_head(&multi->process); e && !result;
3547 result = singlesocket(multi, Curl_node_elem(e));
3555 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3564 * by the multi's connection pool. */
3565 Curl_cpool_multi_socket(multi, s, ev_bitmask);
3579 if(data == multi->cpool.idata)
3606 sigpipe_apply(multi->cpool.idata, &mrc.pipe_st);
3607 Curl_cpool_multi_perform(multi);
3612 *running_handles = (int)multi->num_alive;
3615 result = Curl_update_timer(multi);
3626 struct Curl_multi *multi = m; local
3628 if(!GOOD_MULTI_HANDLE(multi))
3631 if(multi->in_callback)
3638 multi->socket_cb = va_arg(param, curl_socket_callback);
3641 multi->socket_userp = va_arg(param, void *);
3644 multi->push_cb = va_arg(param, curl_push_callback);
3647 multi->push_userp = va_arg(param, void *);
3650 multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0;
3653 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3656 multi->timer_userp = va_arg(param, void *);
3661 multi->maxconnects = (unsigned int)uarg;
3664 multi->max_host_connections = va_arg(param, long);
3667 multi->max_total_connections = va_arg(param, long);
3670 multi->max_shutdown_connections = va_arg(param, long);
3688 multi->max_concurrent_streams = (unsigned int)streams;
3699 /* we define curl_multi_socket() in the public multi.h header */
3704 struct Curl_multi *multi = m; local
3705 if(multi->in_callback)
3707 return multi_socket(multi, FALSE, s, 0, running_handles);
3713 struct Curl_multi *multi = m; local
3714 if(multi->in_callback)
3716 return multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3721 struct Curl_multi *multi = m; local
3722 if(multi->in_callback)
3724 return multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3727 static CURLMcode multi_timeout(struct Curl_multi *multi, argument
3733 if(multi->dead) {
3738 if(multi->timetree) {
3743 multi->timetree = Curl_splay(tv_zero, multi->timetree);
3746 *expire_time = multi->timetree ? multi->timetree->key : tv_zero;
3748 /* 'multi->timetree' will be non-NULL here but the compilers sometimes
3750 if(multi->timetree &&
3751 Curl_timediff_us(multi->timetree->key, now) > 0) {
3753 timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now);
3775 struct Curl_multi *multi = m; local
3778 if(!GOOD_MULTI_HANDLE(multi))
3781 if(multi->in_callback)
3784 return multi_timeout(multi, &expire_time, timeout_ms);
3793 CURLMcode Curl_update_timer(struct Curl_multi *multi) argument
3800 if(!multi->timer_cb || multi->dead)
3802 if(multi_timeout(multi, &expire_ts, &timeout_ms)) {
3806 if(timeout_ms < 0 && multi->last_timeout_ms < 0) {
3815 " last_timeout=%ldms\n", multi->last_timeout_ms);
3820 else if(multi->last_timeout_ms < 0) {
3826 else if(Curl_timediff_us(multi->last_expire_ts, expire_ts)) {
3848 multi->last_expire_ts = expire_ts;
3849 multi->last_timeout_ms = timeout_ms;
3850 set_in_callback(multi, TRUE);
3851 rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3852 set_in_callback(multi, FALSE);
3854 multi->dead = TRUE;
3928 struct Curl_multi *multi = data->multi; local
3932 /* this is only interesting while there is still an associated multi struct
3934 if(!multi)
3970 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3971 &multi->timetree);
3980 multi->timetree = Curl_splayinsert(*curr_expire, multi->timetree,
4020 struct Curl_multi *multi = data->multi; local
4023 /* this is only interesting while there is still an associated multi struct
4025 if(!multi)
4034 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
4035 &multi->timetree);
4056 struct Curl_multi *multi = m; local
4057 if(!GOOD_MULTI_HANDLE(multi))
4060 there = sh_getentry(&multi->sockhash, s);
4070 static void move_pending_to_connect(struct Curl_multi *multi, argument
4079 Curl_llist_append(&multi->process, data, &data->multi_queue);
4101 static void process_pending_handles(struct Curl_multi *multi) argument
4103 struct Curl_llist_node *e = Curl_llist_head(&multi->pending);
4106 move_pending_to_connect(multi, data);
4112 if(data && data->multi)
4113 data->multi->in_callback = value;
4118 return (data && data->multi && data->multi->in_callback);
4121 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi) argument
4123 DEBUGASSERT(multi);
4124 return multi->max_concurrent_streams;
4129 struct Curl_multi *multi = m; local
4130 CURL **a = malloc(sizeof(struct Curl_easy *) * (multi->num_easy + 1));
4134 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
4136 DEBUGASSERT(i < multi->num_easy);
4149 DEBUGASSERT(data->multi);
4152 if(!data->multi) {
4153 failf(data, "transfer has no multi handle");
4160 if(data->multi->xfer_buf_borrowed) {
4165 if(data->multi->xfer_buf &&
4166 data->set.buffer_size > data->multi->xfer_buf_len) {
4168 free(data->multi->xfer_buf);
4169 data->multi->xfer_buf = NULL;
4170 data->multi->xfer_buf_len = 0;
4173 if(!data->multi->xfer_buf) {
4174 data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
4175 if(!data->multi->xfer_buf) {
4180 data->multi->xfer_buf_len = data->set.buffer_size;
4183 data->multi->xfer_buf_borrowed = TRUE;
4184 *pbuf = data->multi->xfer_buf;
4185 *pbuflen = data->multi->xfer_buf_len;
4193 DEBUGASSERT(data->multi);
4194 DEBUGASSERT(!buf || data->multi->xfer_buf == buf);
4195 data->multi->xfer_buf_borrowed = FALSE;
4202 DEBUGASSERT(data->multi);
4205 if(!data->multi) {
4206 failf(data, "transfer has no multi handle");
4213 if(data->multi->xfer_ulbuf_borrowed) {
4218 if(data->multi->xfer_ulbuf &&
4219 data->set.upload_buffer_size > data->multi->xfer_ulbuf_len) {
4221 free(data->multi->xfer_ulbuf);
4222 data->multi->xfer_ulbuf = NULL;
4223 data->multi->xfer_ulbuf_len = 0;
4226 if(!data->multi->xfer_ulbuf) {
4227 data->multi->xfer_ulbuf = malloc((size_t)data->set.upload_buffer_size);
4228 if(!data->multi->xfer_ulbuf) {
4233 data->multi->xfer_ulbuf_len = data->set.upload_buffer_size;
4236 data->multi->xfer_ulbuf_borrowed = TRUE;
4237 *pbuf = data->multi->xfer_ulbuf;
4238 *pbuflen = data->multi->xfer_ulbuf_len;
4246 DEBUGASSERT(data->multi);
4247 DEBUGASSERT(!buf || data->multi->xfer_ulbuf == buf);
4248 data->multi->xfer_ulbuf_borrowed = FALSE;
4255 DEBUGASSERT(data->multi);
4257 if(!data->multi) {
4258 failf(data, "transfer has no multi handle");
4261 if(data->multi->xfer_sockbuf_borrowed) {
4266 if(data->multi->xfer_sockbuf && blen > data->multi->xfer_sockbuf_len) {
4268 free(data->multi->xfer_sockbuf);
4269 data->multi->xfer_sockbuf = NULL;
4270 data->multi->xfer_sockbuf_len = 0;
4273 if(!data->multi->xfer_sockbuf) {
4274 data->multi->xfer_sockbuf = malloc(blen);
4275 if(!data->multi->xfer_sockbuf) {
4279 data->multi->xfer_sockbuf_len = blen;
4282 data->multi->xfer_sockbuf_borrowed = TRUE;
4283 *pbuf = data->multi->xfer_sockbuf;
4291 DEBUGASSERT(data->multi);
4292 DEBUGASSERT(!buf || data->multi->xfer_sockbuf == buf);
4293 data->multi->xfer_sockbuf_borrowed = FALSE;
4296 static void multi_xfer_bufs_free(struct Curl_multi *multi) argument
4298 DEBUGASSERT(multi);
4299 Curl_safefree(multi->xfer_buf);
4300 multi->xfer_buf_len = 0;
4301 multi->xfer_buf_borrowed = FALSE;
4302 Curl_safefree(multi->xfer_ulbuf);
4303 multi->xfer_ulbuf_len = 0;
4304 multi->xfer_ulbuf_borrowed = FALSE;
4305 Curl_safefree(multi->xfer_sockbuf);
4306 multi->xfer_sockbuf_len = 0;
4307 multi->xfer_sockbuf_borrowed = FALSE;
4310 struct Curl_easy *Curl_multi_get_handle(struct Curl_multi *multi, argument
4318 for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
4324 for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) {
4330 for(e = Curl_llist_head(&multi->pending); e; e = Curl_node_next(e)) {