summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/multi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/multi.c')
-rw-r--r--Utilities/cmcurl/lib/multi.c282
1 files changed, 160 insertions, 122 deletions
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index f85284695..0db2a9730 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -31,6 +31,7 @@
#include "progress.h"
#include "easyif.h"
#include "share.h"
+#include "psl.h"
#include "multiif.h"
#include "sendf.h"
#include "timeval.h"
@@ -68,8 +69,8 @@
#define GOOD_MULTI_HANDLE(x) \
((x) && (x)->type == CURL_MULTI_HANDLE)
-static void singlesocket(struct Curl_multi *multi,
- struct Curl_easy *data);
+static CURLMcode singlesocket(struct Curl_multi *multi,
+ struct Curl_easy *data);
static int update_timer(struct Curl_multi *multi);
static CURLMcode add_next_timeout(struct curltime now,
@@ -106,6 +107,16 @@ static const char * const statename[]={
/* function pointer called once when switching TO a state */
typedef void (*init_multistate_func)(struct Curl_easy *data);
+static void Curl_init_completed(struct Curl_easy *data)
+{
+ /* this is a completed transfer */
+
+ /* Important: reset the conn pointer so that we don't point to memory
+ that could be freed anytime */
+ data->easy_conn = NULL;
+ Curl_expire_clear(data); /* stop all timers */
+}
+
/* always use this function to change state, to make debugging easier */
static void mstate(struct Curl_easy *data, CURLMstate state
#ifdef DEBUGBUILD
@@ -115,17 +126,25 @@ static void mstate(struct Curl_easy *data, CURLMstate state
{
CURLMstate oldstate = data->mstate;
static const init_multistate_func finit[CURLM_STATE_LAST] = {
- NULL,
- NULL,
+ NULL, /* INIT */
+ NULL, /* CONNECT_PEND */
Curl_init_CONNECT, /* CONNECT */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- Curl_connect_free /* DO */
- /* the rest is NULL too */
+ NULL, /* WAITRESOLVE */
+ NULL, /* WAITCONNECT */
+ NULL, /* WAITPROXYCONNECT */
+ NULL, /* SENDPROTOCONNECT */
+ NULL, /* PROTOCONNECT */
+ NULL, /* WAITDO */
+ Curl_connect_free, /* DO */
+ NULL, /* DOING */
+ NULL, /* DO_MORE */
+ NULL, /* DO_DONE */
+ NULL, /* WAITPERFORM */
+ NULL, /* PERFORM */
+ NULL, /* TOOFAST */
+ NULL, /* DONE */
+ Curl_init_completed, /* COMPLETED */
+ NULL /* MSGSENT */
};
#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -328,6 +347,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
Curl_llist_init(&multi->pending, multi_freeamsg);
multi->max_pipeline_length = 5;
+ multi->pipelining = CURLPIPE_MULTIPLEX;
/* -1 means it not set by user, use the default value */
multi->maxconnects = -1;
@@ -409,6 +429,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
else
data->state.conn_cache = &multi->conn_cache;
+#ifdef USE_LIBPSL
+ /* Do the same for PSL. */
+ if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
+ data->psl = &data->share->psl;
+ else
+ data->psl = &multi->psl;
+#endif
+
/* This adds the new entry at the 'end' of the doubly-linked circular
list of Curl_easy structs to try and maintain a FIFO queue so
the pipelined requests are in order. */
@@ -449,7 +477,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
happens if the lastcall time is set to the same time when the handle is
removed as when the next handle is added, as then the check in
update_timer() that prevents calling the application multiple times with
- the same timer infor will not trigger and then the new handle's timeout
+ the same timer info will not trigger and then the new handle's timeout
will not be notified to the app.
The work-around is thus simply to clear the 'lastcall' variable to force
@@ -464,6 +492,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->state.conn_cache->closure_handle->set.timeout = data->set.timeout;
data->state.conn_cache->closure_handle->set.server_response_timeout =
data->set.server_response_timeout;
+ data->state.conn_cache->closure_handle->set.no_signal =
+ data->set.no_signal;
update_timer(multi);
return CURLM_OK;
@@ -506,13 +536,16 @@ static CURLcode multi_done(struct connectdata **connp,
/* Stop if multi_done() has already been called */
return CURLE_OK;
+ if(data->mstate == CURLM_STATE_WAITRESOLVE) {
+ /* still waiting for the resolve to complete */
+ (void)Curl_resolver_wait_resolv(conn, NULL);
+ }
+
Curl_getoff_all_pipelines(data, conn);
/* Cleanup possible redirect junk */
- free(data->req.newurl);
- data->req.newurl = NULL;
- free(data->req.location);
- data->req.location = NULL;
+ Curl_safefree(data->req.newurl);
+ Curl_safefree(data->req.location);
switch(status) {
case CURLE_ABORTED_BY_CALLBACK:
@@ -546,7 +579,7 @@ static CURLcode multi_done(struct connectdata **connp,
if(conn->send_pipe.size || conn->recv_pipe.size) {
/* Stop if pipeline is not empty . */
data->easy_conn = NULL;
- DEBUGF(infof(data, "Connection still in use %d/%d, "
+ DEBUGF(infof(data, "Connection still in use %zu/%zu, "
"no more multi_done now!\n",
conn->send_pipe.size, conn->recv_pipe.size));
return CURLE_OK;
@@ -560,6 +593,7 @@ static CURLcode multi_done(struct connectdata **connp,
conn->dns_entry = NULL;
}
Curl_hostcache_prune(data);
+ Curl_safefree(data->state.ulbuf);
/* if the transfer was completed in a paused state there can be buffered
data left to free */
@@ -590,7 +624,7 @@ static CURLcode multi_done(struct connectdata **connp,
#endif
) || conn->bits.close
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
- CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
+ CURLcode res2 = Curl_disconnect(data, conn, premature);
/* If we had an error already, make sure we return that one. But
if we got a new error, return that. */
@@ -608,7 +642,7 @@ static CURLcode multi_done(struct connectdata **connp,
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname);
- /* the connection is no longer in use */
+ /* the connection is no longer in use by this transfer */
if(Curl_conncache_return_conn(conn)) {
/* remember the most recently used connection */
data->state.lastconnect = conn;
@@ -623,7 +657,6 @@ static CURLcode multi_done(struct connectdata **connp,
cache here, and therefore cannot be used from this point on
*/
Curl_free_request_state(data);
-
return result;
}
@@ -698,6 +731,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
Curl_getoff_all_pipelines(data, data->easy_conn);
}
+ if(data->connect_queue.ptr)
+ /* the handle was in the pending list waiting for an available connection,
+ so go ahead and remove it */
+ Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
+
if(data->dns.hostcachetype == HCACHE_MULTI) {
/* stop using the multi handle's DNS cache, *after* the possible
multi_done() call above */
@@ -727,6 +765,12 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
data->easy_conn = NULL;
}
+#ifdef USE_LIBPSL
+ /* Remove the PSL association. */
+ if(data->psl == &multi->psl)
+ data->psl = NULL;
+#endif
+
data->multi = NULL; /* clear the association to this multi handle */
/* make sure there's no pending message in the queue sent from this easy
@@ -831,12 +875,10 @@ static int multi_getsock(struct Curl_easy *data,
of sockets */
int numsocks)
{
- /* If the pipe broke, or if there's no connection left for this easy handle,
- then we MUST bail out now with no bitmask set. The no connection case can
- happen when this is called from curl_multi_remove_handle() =>
- singlesocket() => multi_getsock().
+ /* The no connection case can happen when this is called from
+ curl_multi_remove_handle() => singlesocket() => multi_getsock().
*/
- if(data->state.pipe_broke || !data->easy_conn)
+ if(!data->easy_conn)
return 0;
if(data->mstate > CURLM_STATE_CONNECT &&
@@ -863,7 +905,7 @@ static int multi_getsock(struct Curl_easy *data,
return 0;
case CURLM_STATE_WAITRESOLVE:
- return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
+ return Curl_resolv_getsock(data->easy_conn, socks, numsocks);
case CURLM_STATE_PROTOCONNECT:
case CURLM_STATE_SENDPROTOCONNECT:
@@ -902,7 +944,6 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
struct Curl_easy *data;
int this_max_fd = -1;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
- int bitmap;
int i;
(void)exc_fd_set; /* not used */
@@ -914,7 +955,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
data = multi->easyp;
while(data) {
- bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+ int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
@@ -968,13 +1009,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
if(multi->in_callback)
return CURLM_RECURSIVE_API_CALL;
- /* If the internally desired timeout is actually shorter than requested from
- the outside, then use the shorter time! But only if the internal timer
- is actually larger than -1! */
- (void)multi_timeout(multi, &timeout_internal);
- if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
- timeout_ms = (int)timeout_internal;
-
/* Count up how many fds we have from the multi handle */
data = multi->easyp;
while(data) {
@@ -999,6 +1033,13 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
data = data->next; /* check next handle */
}
+ /* If the internally desired timeout is actually shorter than requested from
+ the outside, then use the shorter time! But only if the internal timer
+ is actually larger than -1! */
+ (void)multi_timeout(multi, &timeout_internal);
+ if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
+ timeout_ms = (int)timeout_internal;
+
curlfds = nfds; /* number of internal file descriptors */
nfds += extra_nfds; /* add the externally provided ones */
@@ -1068,8 +1109,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
int pollrc;
/* wait... */
pollrc = Curl_poll(ufds, nfds, timeout_ms);
- DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
- nfds, timeout_ms, pollrc));
if(pollrc > 0) {
retcode = pollrc;
@@ -1196,7 +1235,7 @@ static CURLcode multi_reconnect_request(struct connectdata **connp)
return result;
/* Resolved, continue with the connection */
- result = Curl_async_resolved(conn, &protocol_done);
+ result = Curl_once_resolved(conn, &protocol_done);
if(result)
return result;
}
@@ -1312,24 +1351,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
bool stream_error = FALSE;
rc = CURLM_OK;
- /* Handle the case when the pipe breaks, i.e., the connection
- we're using gets cleaned up and we're left with nothing. */
- if(data->state.pipe_broke) {
- infof(data, "Pipe broke: handle %p, url = %s\n",
- (void *)data, data->state.path);
-
- if(data->mstate < CURLM_STATE_COMPLETED) {
- /* Head back to the CONNECT state */
- multistate(data, CURLM_STATE_CONNECT);
- rc = CURLM_CALL_MULTI_PERFORM;
- result = CURLE_OK;
- }
-
- data->state.pipe_broke = FALSE;
- data->easy_conn = NULL;
- continue;
- }
-
if(!data->easy_conn &&
data->mstate > CURLM_STATE_CONNECT &&
data->mstate < CURLM_STATE_DONE) {
@@ -1490,7 +1511,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
if(!dns)
- result = Curl_resolver_is_resolved(data->easy_conn, &dns);
+ result = Curl_resolv_check(data->easy_conn, &dns);
/* Update sockets here, because the socket(s) may have been
closed and the application thus needs to be told, even if it
@@ -1503,10 +1524,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(dns) {
/* Perform the next step in the connection phase, and then move on
to the WAITCONNECT state */
- result = Curl_async_resolved(data->easy_conn, &protocol_connect);
+ result = Curl_once_resolved(data->easy_conn, &protocol_connect);
if(result)
- /* if Curl_async_resolved() returns failure, the connection struct
+ /* if Curl_once_resolved() returns failure, the connection struct
is already freed and gone */
data->easy_conn = NULL; /* no more connection */
else {
@@ -1555,6 +1576,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
}
}
+ else if(result)
+ stream_error = TRUE;
break;
#endif
@@ -1585,7 +1608,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case CURLM_STATE_SENDPROTOCONNECT:
result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
- if(!protocol_connect)
+ if(!result && !protocol_connect)
/* switch to waiting state */
multistate(data, CURLM_STATE_PROTOCONNECT);
else if(!result) {
@@ -1684,7 +1707,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
char *newurl = NULL;
followtype follow = FOLLOW_NONE;
CURLcode drc;
- bool retry = FALSE;
drc = Curl_retry_request(data->easy_conn, &newurl);
if(drc) {
@@ -1692,15 +1714,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = drc;
stream_error = TRUE;
}
- else
- retry = (newurl)?TRUE:FALSE;
Curl_posttransfer(data);
drc = multi_done(&data->easy_conn, result, FALSE);
/* When set to retry the connection, we must to go back to
* the CONNECT state */
- if(retry) {
+ if(newurl) {
if(!drc || (drc == CURLE_SEND_ERROR)) {
follow = FOLLOW_RETRY;
drc = Curl_follow(data, newurl, follow);
@@ -1909,6 +1929,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
if(!ret)
retry = (newurl)?TRUE:FALSE;
+ else if(!result)
+ result = ret;
if(retry) {
/* if we are to retry, set the result to OK and consider the
@@ -1968,6 +1990,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
rc = CURLM_CALL_MULTI_PERFORM;
}
}
+ free(newurl);
}
else {
/* after the transfer is done, go DONE */
@@ -1979,18 +2002,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
newurl = data->req.location;
data->req.location = NULL;
result = Curl_follow(data, newurl, FOLLOW_FAKE);
- if(result)
+ free(newurl);
+ if(result) {
stream_error = TRUE;
+ result = multi_done(&data->easy_conn, result, TRUE);
+ }
}
- multistate(data, CURLM_STATE_DONE);
- rc = CURLM_CALL_MULTI_PERFORM;
+ if(!result) {
+ multistate(data, CURLM_STATE_DONE);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
}
}
else if(comeback)
rc = CURLM_CALL_MULTI_PERFORM;
-
- free(newurl);
break;
}
@@ -2040,16 +2066,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
case CURLM_STATE_COMPLETED:
- /* this is a completed transfer, it is likely to still be connected */
-
- /* This node should be delinked from the list now and we should post
- an information message that we are complete. */
-
- /* Important: reset the conn pointer so that we don't point to memory
- that could be freed anytime */
- data->easy_conn = NULL;
-
- Curl_expire_clear(data); /* stop all timers */
break;
case CURLM_STATE_MSGSENT:
@@ -2071,8 +2087,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* NOTE: no attempt to disconnect connections must be made
in the case blocks above - cleanup happens only here */
- data->state.pipe_broke = FALSE;
-
/* Check if we can move pending requests to send pipe */
process_pending_handles(multi); /* connection */
@@ -2087,7 +2101,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* Don't attempt to send data over a connection that timed out */
bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
/* disconnect properly */
- Curl_disconnect(data->easy_conn, dead_connection);
+ Curl_disconnect(data, data->easy_conn, dead_connection);
/* This is where we make sure that the easy_conn pointer is reset.
We don't have to do this in every case block above where a
@@ -2101,6 +2115,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
multistate(data, CURLM_STATE_COMPLETED);
+ rc = CURLM_CALL_MULTI_PERFORM;
}
/* if there's still a connection to use, call the progress function */
else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
@@ -2117,22 +2132,26 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
if(CURLM_STATE_COMPLETED == data->mstate) {
- /* now fill in the Curl_message with this info */
- msg = &data->msg;
-
- msg->extmsg.msg = CURLMSG_DONE;
- msg->extmsg.easy_handle = data;
- msg->extmsg.data.result = result;
+ if(data->set.fmultidone) {
+ /* signal via callback instead */
+ data->set.fmultidone(data, result);
+ }
+ else {
+ /* now fill in the Curl_message with this info */
+ msg = &data->msg;
- rc = multi_addmsg(multi, msg);
+ msg->extmsg.msg = CURLMSG_DONE;
+ msg->extmsg.easy_handle = data;
+ msg->extmsg.data.result = result;
+ rc = multi_addmsg(multi, msg);
+ DEBUGASSERT(!data->easy_conn);
+ }
multistate(data, CURLM_STATE_MSGSENT);
}
} while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
data->result = result;
-
-
return rc;
}
@@ -2220,6 +2239,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
data->state.conn_cache = NULL;
data->multi = NULL; /* clear the association */
+#ifdef USE_LIBPSL
+ if(data->psl == &multi->psl)
+ data->psl = NULL;
+#endif
+
data = nextdata;
}
@@ -2232,6 +2256,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_llist_destroy(&multi->pending, NULL);
Curl_hash_destroy(&multi->hostcache);
+ Curl_psl_destroy(&multi->psl);
/* Free the blacklists by setting them to NULL */
Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
@@ -2286,8 +2311,8 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
* and if we have a different state in any of those sockets from last time we
* call the callback accordingly.
*/
-static void singlesocket(struct Curl_multi *multi,
- struct Curl_easy *data)
+static CURLMcode singlesocket(struct Curl_multi *multi,
+ struct Curl_easy *data)
{
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
int i;
@@ -2334,7 +2359,7 @@ static void singlesocket(struct Curl_multi *multi,
entry = sh_addentry(&multi->sockhash, s, data);
if(!entry)
/* fatal */
- return;
+ return CURLM_OUT_OF_MEMORY;
}
/* we know (entry != NULL) at this point, see the logic above */
@@ -2422,6 +2447,7 @@ static void singlesocket(struct Curl_multi *multi,
memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
data->numsocks = num;
+ return CURLM_OK;
}
void Curl_updatesocket(struct Curl_easy *data)
@@ -2442,20 +2468,23 @@ void Curl_updatesocket(struct Curl_easy *data)
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
{
- struct Curl_multi *multi = conn->data->multi;
- if(multi) {
- /* this is set if this connection is part of a handle that is added to
- a multi handle, and only then this is necessary */
- struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
-
- if(entry) {
- if(multi->socket_cb)
- multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
- multi->socket_userp,
- entry->socketp);
+ if(conn->data) {
+ /* if there's still an easy handle associated with this connection */
+ struct Curl_multi *multi = conn->data->multi;
+ if(multi) {
+ /* this is set if this connection is part of a handle that is added to
+ a multi handle, and only then this is necessary */
+ struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+
+ if(entry) {
+ if(multi->socket_cb)
+ multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+ multi->socket_userp,
+ entry->socketp);
- /* now remove it from the socket hash */
- sh_delentry(&multi->sockhash, s);
+ /* now remove it from the socket hash */
+ sh_delentry(&multi->sockhash, s);
+ }
}
}
}
@@ -2535,8 +2564,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
and callbacks */
if(result != CURLM_BAD_HANDLE) {
data = multi->easyp;
- while(data) {
- singlesocket(multi, data);
+ while(data && !result) {
+ result = singlesocket(multi, data);
data = data->next;
}
}
@@ -2590,10 +2619,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* clear the bitmask only if not locked */
data->easy_conn->cselect_bits = 0;
- if(CURLM_OK >= result)
+ if(CURLM_OK >= result) {
/* get the socket(s) and check if the state has been changed since
last */
- singlesocket(multi, data);
+ result = singlesocket(multi, data);
+ if(result)
+ return result;
+ }
/* Now we fall-through and do the timer-based stuff, since we don't want
to force the user to have to deal with timeouts as long as at least
@@ -2627,10 +2659,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
result = multi_runsingle(multi, now, data);
sigpipe_restore(&pipe_st);
- if(CURLM_OK >= result)
+ if(CURLM_OK >= result) {
/* get the socket(s) and check if the state has been changed since
last */
- singlesocket(multi, data);
+ result = singlesocket(multi, data);
+ if(result)
+ return result;
+ }
}
/* Check if there's one (more) expired timer to deal with! This function
@@ -2677,7 +2712,7 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
multi->push_userp = va_arg(param, void *);
break;
case CURLMOPT_PIPELINING:
- multi->pipelining = va_arg(param, long);
+ multi->pipelining = va_arg(param, long) & CURLPIPE_MULTIPLEX;
break;
case CURLMOPT_TIMERFUNCTION:
multi->timer_cb = va_arg(param, curl_multi_timer_callback);
@@ -2924,7 +2959,6 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
{
struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime;
- int rc;
struct curltime set;
/* this is only interesting while there is still an associated multi struct
@@ -2955,6 +2989,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
Compare if the new time is earlier, and only remove-old/add-new if it
is. */
timediff_t diff = Curl_timediff(set, *nowp);
+ int rc;
if(diff > 0) {
/* The current splay tree entry is sooner than this new expiry time.
@@ -3000,7 +3035,6 @@ void Curl_expire_clear(struct Curl_easy *data)
{
struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime;
- int rc;
/* this is only interesting while there is still an associated multi struct
remaining! */
@@ -3011,6 +3045,7 @@ void Curl_expire_clear(struct Curl_easy *data)
/* Since this is an cleared time, we must remove the previous entry from
the splay tree */
struct curl_llist *list = &data->state.timeoutlist;
+ int rc;
rc = Curl_splayremovebyaddr(multi->timetree,
&data->state.timenode,
@@ -3100,12 +3135,15 @@ static void process_pending_handles(struct Curl_multi *multi)
}
}
-void Curl_set_in_callback(struct Curl_easy *easy, bool value)
+void Curl_set_in_callback(struct Curl_easy *data, bool value)
{
- if(easy->multi_easy)
- easy->multi_easy->in_callback = value;
- else if(easy->multi)
- easy->multi->in_callback = value;
+ /* might get called when there is no data pointer! */
+ if(data) {
+ if(data->multi_easy)
+ data->multi_easy->in_callback = value;
+ else if(data->multi)
+ data->multi->in_callback = value;
+ }
}
bool Curl_is_in_callback(struct Curl_easy *easy)