Lines Matching refs:data

90                               struct Curl_easy *data);
121 typedef void (*init_multistate_func)(struct Curl_easy *data);
124 static void before_perform(struct Curl_easy *data)
126 data->req.chunk = FALSE;
127 Curl_pgrsTime(data, TIMER_PRETRANSFER);
130 static void init_completed(struct Curl_easy *data)
136 Curl_detach_connection(data);
137 Curl_expire_clear(data); /* stop all timers */
141 static void mstate(struct Curl_easy *data, CURLMstate state
147 CURLMstate oldstate = data->mstate;
176 data->mstate = state;
179 if(data->mstate >= MSTATE_PENDING &&
180 data->mstate < MSTATE_COMPLETED) {
181 infof(data,
183 multi_statename[oldstate], multi_statename[data->mstate],
184 (void *)data, lineno);
190 DEBUGASSERT(data->multi->num_alive > 0);
191 data->multi->num_alive--;
196 finit[state](data);
440 static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
443 infof(data, "!!! WARNING !!!");
444 infof(data, "This is a debug build of libcurl, "
455 static bool in_main_list(struct Curl_easy *data)
457 return ((data->mstate != MSTATE_PENDING) &&
458 (data->mstate != MSTATE_MSGSENT));
462 struct Curl_easy *data)
465 data->next = NULL; /* end of the line */
468 last->next = data;
469 data->prev = last;
470 multi->easylp = data; /* the new last node */
474 data->prev = NULL;
475 multi->easylp = multi->easyp = data; /* both first and last */
481 struct Curl_easy *data)
484 if(data->prev)
485 data->prev->next = data->next;
487 multi->easyp = data->next; /* point to first node */
490 if(data->next)
491 data->next->prev = data->prev;
493 multi->easylp = data->prev; /* point to last node */
495 data->prev = data->next = NULL;
500 struct Curl_easy *data)
508 if(!GOOD_EASY_HANDLE(data))
513 if(data->multi)
529 Curl_llist_init(&data->state.timeoutlist, NULL);
537 if(data->set.errorbuffer)
538 data->set.errorbuffer[0] = 0;
542 data->multi = multi;
550 Curl_expire(data, 0, EXPIRE_RUN_NOW);
569 multistate(data, MSTATE_INIT);
573 if(!data->dns.hostcache ||
574 (data->dns.hostcachetype == HCACHE_NONE)) {
575 data->dns.hostcache = &multi->hostcache;
576 data->dns.hostcachetype = HCACHE_MULTI;
580 if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT)))
581 data->state.conn_cache = &data->share->conn_cache;
583 data->state.conn_cache = &multi->conn_cache;
584 data->state.lastconnect_id = -1;
588 if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
589 data->psl = &data->share->psl;
591 data->psl = &multi->psl;
594 link_easy(multi, data);
602 CONNCACHE_LOCK(data);
607 data->state.conn_cache->closure_handle->set.timeout = data->set.timeout;
608 data->state.conn_cache->closure_handle->set.server_response_timeout =
609 data->set.server_response_timeout;
610 data->state.conn_cache->closure_handle->set.no_signal =
611 data->set.no_signal;
612 data->id = data->state.conn_cache->next_easy_id++;
613 if(data->state.conn_cache->next_easy_id <= 0)
614 data->state.conn_cache->next_easy_id = 0;
615 CONNCACHE_UNLOCK(data);
617 multi_warn_debug(multi, data);
638 static CURLcode multi_done(struct Curl_easy *data,
644 struct connectdata *conn = data->conn;
647 DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d",
648 multi_statename[data->mstate],
649 (int)status, (int)premature, data->state.done));
651 DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d",
652 (int)status, (int)premature, data->state.done));
655 if(data->state.done)
660 Curl_resolver_kill(data);
663 Curl_safefree(data->req.newurl);
664 Curl_safefree(data->req.location);
682 result = conn->handler->done(data, status, premature);
689 int rc = Curl_pgrsDone(data);
695 Curl_conn_ev_data_done(data, premature);
697 process_pending_handles(data->multi); /* connection / multiplex */
699 Curl_safefree(data->state.ulbuf);
701 Curl_client_cleanup(data);
703 CONNCACHE_LOCK(data);
704 Curl_detach_connection(data);
707 CONNCACHE_UNLOCK(data);
708 DEBUGF(infof(data, "Connection still in use %zu, "
714 data->state.done = TRUE; /* called just now! */
717 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
720 Curl_hostcache_prune(data);
722 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
737 data->state.recent_conn_id = conn->connection_id;
738 if((data->set.reuse_forbid
749 DEBUGF(infof(data, "multi_done, not reusing connection=%"
753 data->set.reuse_forbid, conn->bits.close, premature,
756 Curl_conncache_remove_conn(data, conn, FALSE);
757 CONNCACHE_UNLOCK(data);
758 Curl_disconnect(data, conn, premature);
776 CONNCACHE_UNLOCK(data);
777 if(Curl_conncache_return_conn(data, conn)) {
779 data->state.lastconnect_id = connection_id;
780 data->state.recent_conn_id = connection_id;
781 infof(data, "%s", buffer);
784 data->state.lastconnect_id = -1;
787 Curl_safefree(data->state.buffer);
791 static int close_connect_only(struct Curl_easy *data,
795 if(data->state.lastconnect_id != conn->connection_id)
807 struct Curl_easy *data)
809 struct Curl_easy *easy = data;
819 if(!GOOD_EASY_HANDLE(data))
823 if(!data->multi)
827 if(data->multi != multi)
833 premature = (data->mstate < MSTATE_COMPLETED) ? TRUE : FALSE;
843 if(data->conn &&
844 data->mstate > MSTATE_DO &&
845 data->mstate < MSTATE_COMPLETED) {
848 streamclose(data->conn, "Removed with partial response");
851 if(data->conn) {
857 (void)multi_done(data, data->result, premature);
860 /* The timer must be shut down before data->multi is set to NULL, else the
863 Curl_expire_clear(data);
865 if(data->connect_queue.ptr) {
868 if(data->mstate == MSTATE_PENDING)
869 Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
871 Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL);
873 if(in_main_list(data))
874 unlink_easy(multi, data);
876 if(data->dns.hostcachetype == HCACHE_MULTI) {
879 data->dns.hostcache = NULL;
880 data->dns.hostcachetype = HCACHE_NONE;
883 Curl_wildcard_dtor(&data->wildcard);
887 data->mstate = MSTATE_COMPLETED;
895 Curl_detach_connection(data);
897 if(data->set.connect_only && !data->multi_easy) {
908 s = Curl_getconnectinfo(data, &c);
910 Curl_conncache_remove_conn(data, c, TRUE);
911 Curl_disconnect(data, c, TRUE);
915 if(data->state.lastconnect_id != -1) {
917 Curl_conncache_foreach(data, data->state.conn_cache,
923 if(data->psl == &multi->psl)
924 data->psl = NULL;
929 data->state.conn_cache = NULL;
931 data->multi = NULL; /* clear the association to this multi handle */
966 * This is the only function that should clear data->conn. This will
967 * occasionally be called with the data->conn pointer already cleared.
969 void Curl_detach_connection(struct Curl_easy *data)
971 struct connectdata *conn = data->conn;
973 Curl_conn_ev_data_detach(conn, data);
974 Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
976 data->conn = NULL;
982 * This is the only function that should assign data->conn
984 void Curl_attach_connection(struct Curl_easy *data,
987 DEBUGASSERT(!data->conn);
989 data->conn = conn;
990 Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data,
991 &data->conn_queue);
993 conn->handler->attach(data, conn);
994 Curl_conn_ev_data_attach(conn, data);
997 static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks)
999 struct connectdata *conn = data->conn;
1011 static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks)
1013 struct connectdata *conn = data->conn;
1015 return conn->handler->proto_getsock(data, conn, socks);
1024 static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks)
1026 struct connectdata *conn = data->conn;
1028 return conn->handler->domore_getsock(data, conn, socks);
1037 static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks)
1039 struct connectdata *conn = data->conn;
1041 return conn->handler->doing_getsock(data, conn, socks);
1050 static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock)
1052 struct connectdata *conn = data->conn;
1057 return conn->handler->perform_getsock(data, conn, sock);
1059 /* Default is to obey the data->req.keepon flags for send/recv */
1062 if(CURL_WANT_RECV(data)) {
1068 if(CURL_WANT_SEND(data)) {
1086 * for transfer `data`. */
1087 static void multi_getsock(struct Curl_easy *data,
1093 Curl_pollset_reset(data, ps);
1094 if(!data->conn)
1097 switch(data->mstate) {
1105 Curl_pollset_add_socks(data, ps, Curl_resolv_getsock);
1111 Curl_pollset_add_socks(data, ps, connecting_getsock);
1112 Curl_conn_adjust_pollset(data, ps);
1117 Curl_pollset_add_socks(data, ps, protocol_getsock);
1118 Curl_conn_adjust_pollset(data, ps);
1123 Curl_pollset_add_socks(data, ps, doing_getsock);
1124 Curl_conn_adjust_pollset(data, ps);
1128 Curl_pollset_add_socks(data, ps, domore_getsock);
1129 Curl_conn_adjust_pollset(data, ps);
1134 Curl_pollset_add_socks(data, ps, perform_getsock);
1135 Curl_conn_adjust_pollset(data, ps);
1149 failf(data, "multi_getsock: unexpected multi state %d", data->mstate);
1162 struct Curl_easy *data;
1175 for(data = multi->easyp; data; data = data->next) {
1176 multi_getsock(data, &ps);
1222 struct Curl_easy *data;
1251 for(data = multi->easyp; data; data = data->next) {
1252 multi_getsock(data, &ps);
1293 for(data = multi->easyp; data; data = data->next) {
1294 multi_getsock(data, &ps);
1433 for(data = multi->easyp; data; data = data->next) {
1434 multi_getsock(data, &ps);
1457 data from it until it receives an error (except EINTR).
1459 when there is no more data, breaking the loop. */
1603 struct Curl_easy *data,
1611 rc = curl_multi_add_handle(multi, data);
1613 struct SingleRequest *k = &data->req;
1617 Curl_init_do(data, NULL);
1620 multistate(data, MSTATE_PERFORMING);
1621 Curl_attach_connection(data, conn);
1627 static CURLcode multi_do(struct Curl_easy *data, bool *done)
1630 struct connectdata *conn = data->conn;
1636 result = conn->handler->do_it(data, done);
1650 static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
1653 struct connectdata *conn = data->conn;
1658 result = conn->handler->do_more(data, complete);
1666 static bool multi_handle_timeout(struct Curl_easy *data,
1673 timeout_ms = Curl_timeleft(data, now, connect_timeout);
1677 if(data->mstate == MSTATE_RESOLVING)
1678 failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
1680 Curl_timediff(*now, data->progress.t_startsingle));
1681 else if(data->mstate == MSTATE_CONNECTING)
1682 failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
1684 Curl_timediff(*now, data->progress.t_startsingle));
1686 struct SingleRequest *k = &data->req;
1688 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
1691 Curl_timediff(*now, data->progress.t_startsingle),
1695 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
1698 Curl_timediff(*now, data->progress.t_startsingle),
1704 if(data->mstate > MSTATE_DO) {
1705 streamclose(data->conn, "Disconnected with pending data");
1709 (void)multi_done(data, *result, TRUE);
1721 static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
1724 struct connectdata *conn = data->conn;
1728 result = conn->handler->connecting(data, done);
1741 static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
1744 struct connectdata *conn = data->conn;
1748 result = conn->handler->doing(data, done);
1761 static CURLcode protocol_connect(struct Curl_easy *data,
1765 struct connectdata *conn = data->conn;
1790 result = conn->handler->connect_it(data, protocol_done);
1809 static CURLcode readrewind(struct Curl_easy *data)
1811 curl_mimepart *mimepart = &data->set.mimepost;
1812 DEBUGASSERT(data->conn);
1814 data->state.rewindbeforesend = FALSE; /* we rewind now */
1816 /* explicitly switch off sending data on this connection now since we are
1818 sending more data on the existing connection until the next transfer
1820 data->req.keepon &= ~KEEP_SEND;
1822 /* We have sent away data. If not using CURLOPT_POSTFIELDS or
1826 if(data->conn->handler->protocol & PROTO_FAMILY_HTTP) {
1827 if(data->state.mimepost)
1828 mimepart = data->state.mimepost;
1831 if(data->set.postfields ||
1832 (data->state.httpreq == HTTPREQ_GET) ||
1833 (data->state.httpreq == HTTPREQ_HEAD))
1835 else if(data->state.httpreq == HTTPREQ_POST_MIME ||
1836 data->state.httpreq == HTTPREQ_POST_FORM) {
1839 failf(data, "Cannot rewind mime/post data");
1844 if(data->set.seek_func) {
1847 Curl_set_in_callback(data, true);
1848 err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
1849 Curl_set_in_callback(data, false);
1851 failf(data, "seek callback returned error %d", (int)err);
1855 else if(data->set.ioctl_func) {
1858 Curl_set_in_callback(data, true);
1859 err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
1860 data->set.ioctl_client);
1861 Curl_set_in_callback(data, false);
1862 infof(data, "the ioctl callback returned %d", (int)err);
1865 failf(data, "ioctl callback returned error %d", (int)err);
1873 if(data->state.fread_func == (curl_read_callback)fread) {
1874 if(-1 != fseek(data->state.in, 0, SEEK_SET))
1880 failf(data, "necessary data rewind wasn't possible");
1892 CURLcode Curl_preconnect(struct Curl_easy *data)
1894 if(!data->state.buffer) {
1895 data->state.buffer = malloc(data->set.buffer_size + 1);
1896 if(!data->state.buffer)
1910 struct Curl_easy *data)
1924 if(!GOOD_EASY_HANDLE(data))
1931 Curl_posttransfer(data);
1932 multi_done(data, result, FALSE);
1933 multistate(data, MSTATE_COMPLETED);
1936 multi_warn_debug(multi, data);
1945 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
1949 if(data->mstate > MSTATE_CONNECT &&
1950 data->mstate < MSTATE_COMPLETED) {
1952 DEBUGASSERT(data->conn);
1953 if(!data->conn)
1957 if(data->conn &&
1958 (data->mstate >= MSTATE_CONNECT) &&
1959 (data->mstate < MSTATE_COMPLETED)) {
1969 if(multi_handle_timeout(data, nowp, &stream_error, &result, FALSE)) {
1975 switch(data->mstate) {
1978 result = Curl_pretransfer(data);
1982 multistate(data, MSTATE_CONNECT);
1983 *nowp = Curl_pgrsTime(data, TIMER_STARTOP);
1991 result = Curl_preconnect(data);
1995 *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
1996 if(data->set.timeout)
1997 Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
1999 if(data->set.connecttimeout)
2000 Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
2002 result = Curl_connect(data, &async, &connected);
2006 multistate(data, MSTATE_PENDING);
2009 Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
2010 &data->connect_queue);
2012 unlink_easy(multi, data);
2016 else if(data->state.previouslypending) {
2018 infof(data, "Transfer was pending, now try another");
2019 process_pending_handles(data->multi);
2023 *nowp = Curl_pgrsTime(data, TIMER_POSTQUEUE);
2026 multistate(data, MSTATE_RESOLVING);
2034 multistate(data, MSTATE_PROTOCONNECT);
2036 multistate(data, MSTATE_CONNECTING);
2046 struct connectdata *conn = data->conn;
2061 dns = Curl_fetch_addr(data, hostname, (int)conn->port);
2065 data->state.async.dns = dns;
2066 data->state.async.done = TRUE;
2069 infof(data, "Hostname '%s' was found in DNS cache", hostname);
2073 result = Curl_resolv_check(data, &dns);
2081 rc = singlesocket(multi, data);
2088 result = Curl_once_resolved(data, &connected);
2093 data->conn = NULL; /* no more connection */
2098 multistate(data, MSTATE_PROTOCONNECT);
2100 multistate(data, MSTATE_CONNECTING);
2116 DEBUGASSERT(data->conn);
2117 result = Curl_http_connect(data, &protocol_connected);
2119 if(data->conn->bits.proxy_connect_closed) {
2123 multi_done(data, CURLE_OK, FALSE);
2124 multistate(data, MSTATE_CONNECT);
2131 multistate(data, MSTATE_PROTOCONNECT);
2140 DEBUGASSERT(data->conn);
2141 result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
2144 multistate(data, MSTATE_PROTOCONNECT);
2148 Curl_posttransfer(data);
2149 multi_done(data, result, TRUE);
2156 if(data->state.rewindbeforesend)
2157 result = readrewind(data);
2159 if(!result && data->conn->bits.reuse) {
2163 multistate(data, MSTATE_DO);
2168 result = protocol_connect(data, &protocol_connected);
2171 multistate(data, MSTATE_PROTOCONNECTING);
2176 multistate(data, MSTATE_DO);
2181 Curl_posttransfer(data);
2182 multi_done(data, result, TRUE);
2189 result = protocol_connecting(data, &protocol_connected);
2192 multistate(data, MSTATE_DO);
2197 Curl_posttransfer(data);
2198 multi_done(data, result, TRUE);
2204 if(data->set.fprereq) {
2208 Curl_set_in_callback(data, true);
2209 prereq_rc = data->set.fprereq(data->set.prereq_userp,
2210 data->info.conn_primary_ip,
2211 data->info.conn_local_ip,
2212 data->info.conn_primary_port,
2213 data->info.conn_local_port);
2214 Curl_set_in_callback(data, false);
2216 failf(data, "operation aborted by pre-request callback");
2219 Curl_posttransfer(data);
2220 multi_done(data, result, FALSE);
2226 if(data->set.connect_only == 1) {
2228 connkeep(data->conn, "CONNECT_ONLY");
2229 multistate(data, MSTATE_DONE);
2235 result = multi_do(data, &dophase_done);
2237 /* When multi_do() returns failure, data->conn might be NULL! */
2243 if(data->state.wildcardmatch) {
2244 struct WildcardData *wc = data->wildcard;
2247 multi_done(data, CURLE_OK, FALSE);
2250 multistate(data, data->conn ?
2259 multistate(data, MSTATE_DOING);
2264 else if(data->conn->bits.do_more) {
2267 multistate(data, MSTATE_DOING_MORE);
2272 multistate(data, MSTATE_DID);
2277 data->conn->bits.reuse) {
2287 drc = Curl_retry_request(data, &newurl);
2294 Curl_posttransfer(data);
2295 drc = multi_done(data, result, FALSE);
2302 drc = Curl_follow(data, newurl, follow);
2304 multistate(data, MSTATE_CONNECT);
2326 Curl_posttransfer(data);
2327 if(data->conn)
2328 multi_done(data, result, FALSE);
2336 DEBUGASSERT(data->conn);
2337 result = protocol_doing(data, &dophase_done);
2341 multistate(data, data->conn->bits.do_more?
2348 Curl_posttransfer(data);
2349 multi_done(data, result, FALSE);
2358 DEBUGASSERT(data->conn);
2359 result = multi_do_more(data, &control);
2365 multistate(data, control == 1?
2374 Curl_posttransfer(data);
2375 multi_done(data, result, FALSE);
2381 DEBUGASSERT(data->conn);
2382 if(data->conn->bits.multiplex)
2388 if((data->conn->sockfd != CURL_SOCKET_BAD) ||
2389 (data->conn->writesockfd != CURL_SOCKET_BAD))
2390 multistate(data, MSTATE_PERFORMING);
2393 if(data->state.wildcardmatch &&
2394 ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
2395 data->wildcard->state = CURLWC_DONE;
2398 multistate(data, MSTATE_DONE);
2404 DEBUGASSERT(data->conn);
2406 if(Curl_pgrsUpdate(data))
2409 result = Curl_speedcheck(data, *nowp);
2412 if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2414 streamclose(data->conn, "Transfer returned error");
2416 Curl_posttransfer(data);
2417 multi_done(data, result, TRUE);
2421 if(data->set.max_send_speed)
2423 Curl_pgrsLimitWaitTime(data->progress.uploaded,
2424 data->progress.ul_limit_size,
2425 data->set.max_send_speed,
2426 data->progress.ul_limit_start,
2430 if(data->set.max_recv_speed)
2432 Curl_pgrsLimitWaitTime(data->progress.downloaded,
2433 data->progress.dl_limit_size,
2434 data->set.max_recv_speed,
2435 data->progress.dl_limit_start,
2439 multistate(data, MSTATE_PERFORMING);
2440 Curl_ratelimit(data, *nowp);
2443 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2445 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2453 DEBUGASSERT(data->state.buffer);
2456 if(data->set.max_send_speed)
2457 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
2458 data->progress.ul_limit_size,
2459 data->set.max_send_speed,
2460 data->progress.ul_limit_start,
2465 if(data->set.max_recv_speed)
2466 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
2467 data->progress.dl_limit_size,
2468 data->set.max_recv_speed,
2469 data->progress.dl_limit_start,
2473 Curl_ratelimit(data, *nowp);
2474 multistate(data, MSTATE_RATELIMITING);
2476 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2478 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2482 /* read/write data if it is ready to do so */
2483 result = Curl_readwrite(data, &done);
2490 CURLcode ret = Curl_retry_request(data, &newurl);
2504 Curl_h2_http_1_1_error(data)) {
2505 CURLcode ret = Curl_retry_request(data, &newurl);
2508 infof(data, "Downgrades to HTTP/1.1");
2509 streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
2510 data->state.httpwant = CURL_HTTP_VERSION_1_1;
2512 data->state.errorbuf = FALSE;
2515 newurl = strdup(data->state.url);
2532 * happened in the data connection.
2535 if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2537 streamclose(data->conn, "Transfer returned error");
2539 Curl_posttransfer(data);
2540 multi_done(data, result, TRUE);
2545 Curl_posttransfer(data);
2549 if(data->req.newurl || retry) {
2555 newurl = data->req.newurl;
2556 data->req.newurl = NULL;
2561 (void)multi_done(data, CURLE_OK, FALSE);
2563 result = Curl_follow(data, newurl, follow);
2565 multistate(data, MSTATE_CONNECT);
2575 if(data->req.location) {
2577 newurl = data->req.location;
2578 data->req.location = NULL;
2579 result = Curl_follow(data, newurl, FOLLOW_FAKE);
2583 result = multi_done(data, result, TRUE);
2588 multistate(data, MSTATE_DONE);
2593 else if(data->state.select_bits) {
2597 Curl_expire(data, 0, EXPIRE_RUN_NOW);
2606 if(data->conn) {
2609 if(data->conn->bits.multiplex)
2614 res = multi_done(data, result, FALSE);
2622 if(data->state.wildcardmatch) {
2623 if(data->wildcard->state != CURLWC_DONE) {
2626 multistate(data, MSTATE_INIT);
2633 multistate(data, MSTATE_COMPLETED);
2649 if(data->conn &&
2650 data->mstate >= MSTATE_CONNECT &&
2651 data->mstate < MSTATE_DO &&
2660 multi_handle_timeout(data, nowp, &stream_error, &result, TRUE);
2665 if(data->mstate < MSTATE_COMPLETED) {
2678 if(data->conn) {
2680 /* Don't attempt to send data over a connection that timed out */
2682 struct connectdata *conn = data->conn;
2687 Curl_detach_connection(data);
2690 Curl_conncache_remove_conn(data, conn, TRUE);
2693 Curl_disconnect(data, conn, dead_connection);
2696 else if(data->mstate == MSTATE_CONNECT) {
2698 (void)Curl_posttransfer(data);
2701 multistate(data, MSTATE_COMPLETED);
2705 else if(data->conn && Curl_pgrsUpdate(data)) {
2709 streamclose(data->conn, "Aborted by callback");
2712 multistate(data, (data->mstate < MSTATE_DONE)?
2718 if(MSTATE_COMPLETED == data->mstate) {
2719 if(data->set.fmultidone) {
2721 data->set.fmultidone(data, result);
2725 msg = &data->msg;
2728 msg->extmsg.easy_handle = data;
2729 msg->extmsg.data.result = result;
2732 DEBUGASSERT(!data->conn);
2734 multistate(data, MSTATE_MSGSENT);
2737 Curl_llist_insert_next(&multi->msgsent, multi->msgsent.tail, data,
2738 &data->connect_queue);
2740 unlink_easy(multi, data);
2745 data->result = result;
2752 struct Curl_easy *data;
2763 data = multi->easyp;
2764 if(data) {
2766 bool nosig = data->set.no_signal;
2768 sigpipe_ignore(data, &pipe_st);
2774 struct Curl_easy *datanext = data->next;
2775 if(data->set.no_signal != nosig) {
2777 sigpipe_ignore(data, &pipe_st);
2778 nosig = data->set.no_signal;
2780 result = multi_runsingle(multi, &now, data);
2783 data = datanext; /* operate on next handle */
2784 } while(data);
2820 struct Curl_easy *data = e->ptr;
2821 DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
2822 data->multi = NULL;
2828 struct Curl_easy *data;
2840 data = multi->easyp;
2841 while(data) {
2842 nextdata = data->next;
2843 if(!data->state.done && data->conn)
2845 (void)multi_done(data, CURLE_OK, TRUE);
2846 if(data->dns.hostcachetype == HCACHE_MULTI) {
2848 Curl_hostcache_clean(data, data->dns.hostcache);
2849 data->dns.hostcache = NULL;
2850 data->dns.hostcachetype = HCACHE_NONE;
2854 data->state.conn_cache = NULL;
2855 data->multi = NULL; /* clear the association */
2858 if(data->psl == &multi->psl)
2859 data->psl = NULL;
2862 data = nextdata;
2936 struct Curl_easy *data)
2946 multi_getsock(data, &cur_poll);
2965 for(j = 0; j< data->last_poll.num; j++) {
2966 if(s == data->last_poll.sockets[j]) {
2967 last_action = data->last_poll.actions[j];
2998 /* add 'data' to the transfer hash on this socket! */
2999 if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
3000 sizeof(struct Curl_easy *), data)) {
3016 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
3032 for(i = 0; i< data->last_poll.num; i++) {
3035 s = data->last_poll.sockets[i];
3050 unsigned char oldactions = data->last_poll.actions[i];
3060 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3072 if(Curl_hash_delete(&entry->transfers, (char *)&data,
3081 memcpy(&data->last_poll, &cur_poll, sizeof(data->last_poll));
3085 CURLcode Curl_updatesocket(struct Curl_easy *data)
3087 if(singlesocket(data->multi, data))
3103 void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
3105 if(data) {
3107 struct Curl_multi *multi = data->multi;
3117 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3197 struct Curl_easy *data = NULL;
3211 data = multi->easyp;
3212 while(data && !result) {
3213 result = singlesocket(multi, data);
3214 data = data->next;
3239 data = (struct Curl_easy *)he->ptr;
3240 DEBUGASSERT(data);
3241 DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
3243 if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
3245 data->state.select_bits = (unsigned char)ev_bitmask;
3247 Curl_expire(data, 0, EXPIRE_RUN_NOW);
3254 data = NULL; /* set data to NULL again to avoid calling
3271 * to process in the splay and 'data' will be re-assigned for every expired
3275 /* the first loop lap 'data' can be NULL */
3276 if(data) {
3279 nosig = data->set.no_signal; /* initial state */
3280 sigpipe_ignore(data, &pipe_st);
3282 else if(data->set.no_signal != nosig) {
3284 sigpipe_ignore(data, &pipe_st);
3285 nosig = data->set.no_signal; /* remember new state */
3287 result = multi_runsingle(multi, &now, data);
3292 result = singlesocket(multi, data);
3303 data = t->payload; /* assign this for next loop */
3533 multi_deltimeout(struct Curl_easy *data, expire_id eid)
3536 struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3555 multi_addtimeout(struct Curl_easy *data,
3563 struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3565 node = &data->state.expires[eid];
3601 void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
3603 struct Curl_multi *multi = data->multi;
3604 struct curltime *nowp = &data->state.expiretime;
3624 multi_deltimeout(data, id);
3628 multi_addtimeout(data, &set, id);
3645 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3648 infof(data, "Internal error removing splay node = %d", rc);
3654 data->state.timenode.payload = data;
3656 &data->state.timenode);
3665 void Curl_expire_done(struct Curl_easy *data, expire_id id)
3668 multi_deltimeout(data, id);
3676 void Curl_expire_clear(struct Curl_easy *data)
3678 struct Curl_multi *multi = data->multi;
3679 struct curltime *nowp = &data->state.expiretime;
3689 struct Curl_llist *list = &data->state.timeoutlist;
3692 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3695 infof(data, "Internal error clearing splay node = %d", rc);
3703 infof(data, "Expire cleared");
3742 void Curl_multiuse_state(struct Curl_easy *data,
3746 DEBUGASSERT(data);
3747 DEBUGASSERT(data->multi);
3748 conn = data->conn;
3753 process_pending_handles(data->multi);
3762 struct Curl_easy *data = e->ptr;
3764 DEBUGASSERT(data->mstate == MSTATE_PENDING);
3767 link_easy(multi, data);
3769 multistate(data, MSTATE_CONNECT);
3775 Curl_expire(data, 0, EXPIRE_RUN_NOW);
3778 data->state.previouslypending = TRUE;
3782 void Curl_set_in_callback(struct Curl_easy *data, bool value)
3784 /* might get called when there is no data pointer! */
3785 if(data) {
3786 if(data->multi_easy)
3787 data->multi_easy->in_callback = value;
3788 else if(data->multi)
3789 data->multi->in_callback = value;