mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
multi: use a fixed array of timers instead of malloc
... since the total amount is low this is faster, easier and reduces memory overhead. Also, Curl_expire_done() can now mark an expire timeout as done so that it never times out. Closes #1472
This commit is contained in:
parent
e9fd794a61
commit
31b39c40cf
@ -232,7 +232,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|||||||
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
||||||
if(milli == 0)
|
if(milli == 0)
|
||||||
milli += 10;
|
milli += 10;
|
||||||
Curl_expire_latest(conn->data, milli, EXPIRE_ARES);
|
Curl_expire_latest(conn->data, milli, EXPIRE_ASYNC_NAME);
|
||||||
|
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -540,7 +540,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
td->poll_interval = 250;
|
td->poll_interval = 250;
|
||||||
|
|
||||||
td->interval_end = elapsed + td->poll_interval;
|
td->interval_end = elapsed + td->poll_interval;
|
||||||
Curl_expire(conn->data, td->poll_interval);
|
Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
@ -1044,7 +1044,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
|||||||
if(!result &&
|
if(!result &&
|
||||||
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
||||||
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
|
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
|
||||||
Curl_expire(data, 0, EXPIRE_UNPAUSE); /* get this handle going again */
|
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2746,6 +2746,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
data->req.upload_done = TRUE;
|
data->req.upload_done = TRUE;
|
||||||
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
|
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
|
||||||
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
|
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
|
||||||
|
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3042,6 +3043,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
|||||||
if(k->exp100 > EXP100_SEND_DATA) {
|
if(k->exp100 > EXP100_SEND_DATA) {
|
||||||
k->exp100 = EXP100_SEND_DATA;
|
k->exp100 = EXP100_SEND_DATA;
|
||||||
k->keepon |= KEEP_SEND;
|
k->keepon |= KEEP_SEND;
|
||||||
|
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 101:
|
case 101:
|
||||||
@ -3168,6 +3170,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
|||||||
* request body has been sent we stop sending and mark the
|
* request body has been sent we stop sending and mark the
|
||||||
* connection for closure after we've read the entire response.
|
* connection for closure after we've read the entire response.
|
||||||
*/
|
*/
|
||||||
|
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||||
if(!k->upload_done) {
|
if(!k->upload_done) {
|
||||||
if(data->set.http_keep_sending_on_error) {
|
if(data->set.http_keep_sending_on_error) {
|
||||||
infof(data, "HTTP error before end of send, keep sending\n");
|
infof(data, "HTTP error before end of send, keep sending\n");
|
||||||
|
@ -569,7 +569,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
|
|
||||||
/* if we receive data for another handle, wake that up */
|
/* if we receive data for another handle, wake that up */
|
||||||
if(conn_s->data != data_s)
|
if(conn_s->data != data_s)
|
||||||
Curl_expire(data_s, 0, EXPIRE_H2DATA);
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_PUSH_PROMISE:
|
case NGHTTP2_PUSH_PROMISE:
|
||||||
@ -646,7 +646,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||||||
|
|
||||||
/* if we receive data for another handle, wake that up */
|
/* if we receive data for another handle, wake that up */
|
||||||
if(conn->data != data_s)
|
if(conn->data != data_s)
|
||||||
Curl_expire(data_s, 0, EXPIRE_H2DATA);
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||||
|
|
||||||
DEBUGF(infof(data_s, "%zu data received for stream %u "
|
DEBUGF(infof(data_s, "%zu data received for stream %u "
|
||||||
"(%zu left in buffer %p, total %zu)\n",
|
"(%zu left in buffer %p, total %zu)\n",
|
||||||
@ -909,7 +909,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
|
Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
|
||||||
/* if we receive data for another handle, wake that up */
|
/* if we receive data for another handle, wake that up */
|
||||||
if(conn->data != data_s)
|
if(conn->data != data_s)
|
||||||
Curl_expire(data_s, 0, EXPIRE_H2DATA);
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||||
|
|
||||||
DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
||||||
stream->status_code, data_s));
|
stream->status_code, data_s));
|
||||||
@ -925,7 +925,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
|
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
|
||||||
/* if we receive data for another handle, wake that up */
|
/* if we receive data for another handle, wake that up */
|
||||||
if(conn->data != data_s)
|
if(conn->data != data_s)
|
||||||
Curl_expire(data_s, 0, EXPIRE_H2DATA);
|
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||||
|
|
||||||
DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
|
DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
|
||||||
value));
|
value));
|
||||||
|
@ -122,7 +122,8 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
|||||||
--list->size;
|
--list->size;
|
||||||
|
|
||||||
/* call the dtor() last for when it actually frees the 'e' memory itself */
|
/* call the dtor() last for when it actually frees the 'e' memory itself */
|
||||||
list->dtor(user, ptr);
|
if(list->dtor)
|
||||||
|
list->dtor(user, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
62
lib/multi.c
62
lib/multi.c
@ -99,8 +99,6 @@ static const char * const statename[]={
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void multi_freetimeout(void *a, void *b);
|
|
||||||
|
|
||||||
/* function pointer called once when switching TO a state */
|
/* function pointer called once when switching TO a state */
|
||||||
typedef void (*init_multistate_func)(struct Curl_easy *data);
|
typedef void (*init_multistate_func)(struct Curl_easy *data);
|
||||||
|
|
||||||
@ -369,7 +367,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||||||
return CURLM_ADDED_ALREADY;
|
return CURLM_ADDED_ALREADY;
|
||||||
|
|
||||||
/* Initialize timeout list for this handle */
|
/* Initialize timeout list for this handle */
|
||||||
Curl_llist_init(&data->state.timeoutlist, multi_freetimeout);
|
Curl_llist_init(&data->state.timeoutlist, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No failure allowed in this function beyond this point. And no
|
* No failure allowed in this function beyond this point. And no
|
||||||
@ -430,7 +428,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||||||
sockets that time-out or have actions will be dealt with. Since this
|
sockets that time-out or have actions will be dealt with. Since this
|
||||||
handle has no action yet, we make sure it times out to get things to
|
handle has no action yet, we make sure it times out to get things to
|
||||||
happen. */
|
happen. */
|
||||||
Curl_expire(data, 0, EXPIRE_ADD_HANDLE);
|
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||||
|
|
||||||
/* increase the node-counter */
|
/* increase the node-counter */
|
||||||
multi->num_easy++;
|
multi->num_easy++;
|
||||||
@ -1941,7 +1939,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
/* expire the new receiving pipeline head */
|
/* expire the new receiving pipeline head */
|
||||||
if(data->easy_conn->recv_pipe.head)
|
if(data->easy_conn->recv_pipe.head)
|
||||||
Curl_expire_latest(data->easy_conn->recv_pipe.head->ptr, 0,
|
Curl_expire_latest(data->easy_conn->recv_pipe.head->ptr, 0,
|
||||||
EXPIRE_PIPELINE_READ);
|
EXPIRE_RUN_NOW);
|
||||||
|
|
||||||
/* Check if we can move pending requests to send pipe */
|
/* Check if we can move pending requests to send pipe */
|
||||||
Curl_multi_process_pending_handles(multi);
|
Curl_multi_process_pending_handles(multi);
|
||||||
@ -2482,12 +2480,6 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct time_node {
|
|
||||||
struct curl_llist_element list;
|
|
||||||
struct timeval time;
|
|
||||||
expire_id id;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add_next_timeout()
|
* add_next_timeout()
|
||||||
*
|
*
|
||||||
@ -2859,35 +2851,20 @@ static int update_timer(struct Curl_multi *multi)
|
|||||||
return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
|
return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* multi_freetimeout()
|
|
||||||
*
|
|
||||||
* Callback used by the llist system when a single timeout list entry is
|
|
||||||
* destroyed.
|
|
||||||
*/
|
|
||||||
static void multi_freetimeout(void *user, void *entryptr)
|
|
||||||
{
|
|
||||||
(void)user;
|
|
||||||
|
|
||||||
/* the entry was plain malloc()'ed */
|
|
||||||
free(entryptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* multi_deltimeout()
|
* multi_deltimeout()
|
||||||
*
|
*
|
||||||
* Remove a given timestamp from the list of timeouts.
|
* Remove a given timestamp from the list of timeouts.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
multi_deltimeout(struct Curl_easy *data, expire_id id)
|
multi_deltimeout(struct Curl_easy *data, expire_id eid)
|
||||||
{
|
{
|
||||||
struct curl_llist_element *e;
|
struct curl_llist_element *e;
|
||||||
struct curl_llist *timeoutlist = &data->state.timeoutlist;
|
struct curl_llist *timeoutlist = &data->state.timeoutlist;
|
||||||
|
/* find and remove the specific node from the list */
|
||||||
/* find and remove the node(s) from the list */
|
|
||||||
for(e = timeoutlist->head; e; e = e->next) {
|
for(e = timeoutlist->head; e; e = e->next) {
|
||||||
struct time_node *node = (struct time_node *)e->ptr;
|
struct time_node *n = (struct time_node *)e->ptr;
|
||||||
if(node->id == id) {
|
if(n->eid == eid) {
|
||||||
Curl_llist_remove(timeoutlist, e, NULL);
|
Curl_llist_remove(timeoutlist, e, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2904,7 +2881,7 @@ multi_deltimeout(struct Curl_easy *data, expire_id id)
|
|||||||
static CURLMcode
|
static CURLMcode
|
||||||
multi_addtimeout(struct Curl_easy *data,
|
multi_addtimeout(struct Curl_easy *data,
|
||||||
struct timeval *stamp,
|
struct timeval *stamp,
|
||||||
int id)
|
expire_id eid)
|
||||||
{
|
{
|
||||||
struct curl_llist_element *e;
|
struct curl_llist_element *e;
|
||||||
struct time_node *node;
|
struct time_node *node;
|
||||||
@ -2912,13 +2889,11 @@ multi_addtimeout(struct Curl_easy *data,
|
|||||||
size_t n;
|
size_t n;
|
||||||
struct curl_llist *timeoutlist = &data->state.timeoutlist;
|
struct curl_llist *timeoutlist = &data->state.timeoutlist;
|
||||||
|
|
||||||
node = malloc(sizeof(struct time_node));
|
node = &data->state.expires[eid];
|
||||||
if(!node)
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* copy the timestamp and id */
|
/* copy the timestamp and id */
|
||||||
memcpy(&node->time, stamp, sizeof(*stamp));
|
memcpy(&node->time, stamp, sizeof(*stamp));
|
||||||
node->id = id;
|
node->eid = eid; /* also marks it as in use */
|
||||||
|
|
||||||
n = Curl_llist_count(timeoutlist);
|
n = Curl_llist_count(timeoutlist);
|
||||||
infof(data, "TIMEOUTS %zd\n", n);
|
infof(data, "TIMEOUTS %zd\n", n);
|
||||||
@ -2949,9 +2924,7 @@ multi_addtimeout(struct Curl_easy *data,
|
|||||||
* The timeout will be added to a queue of timeouts if it defines a moment in
|
* The timeout will be added to a queue of timeouts if it defines a moment in
|
||||||
* time that is later than the current head of queue.
|
* time that is later than the current head of queue.
|
||||||
*
|
*
|
||||||
* If 'id' is given (non-zero), expire will replace a former timeout using the
|
* Expire replaces a former timeout using the same id if already set.
|
||||||
* same id. id is also a good way to keep track of the purpose of each
|
|
||||||
* timeout.
|
|
||||||
*/
|
*/
|
||||||
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
|
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
|
||||||
{
|
{
|
||||||
@ -3056,6 +3029,17 @@ void Curl_expire_latest(struct Curl_easy *data, time_t milli, expire_id id)
|
|||||||
Curl_expire(data, milli, id);
|
Curl_expire(data, milli, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_expire_done()
|
||||||
|
*
|
||||||
|
* Removes the expire timer. Marks it as done.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Curl_expire_done(struct Curl_easy *data, expire_id id)
|
||||||
|
{
|
||||||
|
/* remove the timer, if there */
|
||||||
|
multi_deltimeout(data, id);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_expire_clear()
|
* Curl_expire_clear()
|
||||||
@ -3160,7 +3144,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
|||||||
Curl_llist_remove(&multi->pending, e, NULL);
|
Curl_llist_remove(&multi->pending, e, NULL);
|
||||||
|
|
||||||
/* Make sure that the handle will be processed soonish. */
|
/* Make sure that the handle will be processed soonish. */
|
||||||
Curl_expire_latest(data, 0, EXPIRE_MULTI_PENDING);
|
Curl_expire_latest(data, 0, EXPIRE_RUN_NOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
e = next; /* operate on next handle */
|
e = next; /* operate on next handle */
|
||||||
|
@ -26,28 +26,10 @@
|
|||||||
* Prototypes for library-wide functions provided by multi.c
|
* Prototypes for library-wide functions provided by multi.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Timers */
|
|
||||||
typedef enum {
|
|
||||||
EXPIRE_SPEEDCHECK,
|
|
||||||
EXPIRE_H2DATA,
|
|
||||||
EXPIRE_PIPELINE_SEND,
|
|
||||||
EXPIRE_PIPELINE_READ,
|
|
||||||
EXPIRE_ADD_HANDLE,
|
|
||||||
EXPIRE_TOOFAST,
|
|
||||||
EXPIRE_UNPAUSE,
|
|
||||||
EXPIRE_ARES,
|
|
||||||
EXPIRE_MULTI_PENDING,
|
|
||||||
EXPIRE_DNS_PER_NAME,
|
|
||||||
EXPIRE_HAPPY_EYEBALLS,
|
|
||||||
EXPIRE_100_TIMEOUT,
|
|
||||||
EXPIRE_TIMEOUT,
|
|
||||||
EXPIRE_CONNECTTIMEOUT,
|
|
||||||
EXPIRE_LAST /* not an actual timer, used as a marker only */
|
|
||||||
} expire_id;
|
|
||||||
|
|
||||||
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
|
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
|
||||||
void Curl_expire_clear(struct Curl_easy *data);
|
void Curl_expire_clear(struct Curl_easy *data);
|
||||||
void Curl_expire_latest(struct Curl_easy *data, time_t milli, expire_id);
|
void Curl_expire_latest(struct Curl_easy *data, time_t milli, expire_id);
|
||||||
|
void Curl_expire_done(struct Curl_easy *data, expire_id id);
|
||||||
bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
|
bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
|
||||||
void Curl_multi_handlePipeBreak(struct Curl_easy *data);
|
void Curl_multi_handlePipeBreak(struct Curl_easy *data);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
|
|||||||
if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
|
if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
|
||||||
/* this is a new one as head, expire it */
|
/* this is a new one as head, expire it */
|
||||||
Curl_pipeline_leave_write(conn); /* not in use yet */
|
Curl_pipeline_leave_write(conn); /* not in use yet */
|
||||||
Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_PIPELINE_SEND);
|
Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* enable for pipeline debugging */
|
#if 0 /* enable for pipeline debugging */
|
||||||
@ -148,7 +148,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
|
|||||||
infof(conn->data, "%p is at send pipe head B!\n",
|
infof(conn->data, "%p is at send pipe head B!\n",
|
||||||
(void *)conn->send_pipe.head->ptr);
|
(void *)conn->send_pipe.head->ptr);
|
||||||
#endif
|
#endif
|
||||||
Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_PIPELINE_READ);
|
Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The receiver's list is not really interesting here since either this
|
/* The receiver's list is not really interesting here since either this
|
||||||
|
@ -1891,7 +1891,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
/* since we don't really wait for anything at this point, we want the
|
/* since we don't really wait for anything at this point, we want the
|
||||||
state machine to move on as soon as possible so we set a very short
|
state machine to move on as soon as possible so we set a very short
|
||||||
timeout here */
|
timeout here */
|
||||||
Curl_expire(data, 0);
|
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||||
|
|
||||||
state(conn, SSH_STOP);
|
state(conn, SSH_STOP);
|
||||||
}
|
}
|
||||||
|
@ -1139,6 +1139,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* we've waited long enough, continue anyway */
|
/* we've waited long enough, continue anyway */
|
||||||
k->exp100 = EXP100_SEND_DATA;
|
k->exp100 = EXP100_SEND_DATA;
|
||||||
k->keepon |= KEEP_SEND;
|
k->keepon |= KEEP_SEND;
|
||||||
|
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||||
infof(data, "Done waiting for 100-continue\n");
|
infof(data, "Done waiting for 100-continue\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1314,6 +1314,30 @@ struct tempbuf {
|
|||||||
Curl_client_write() */
|
Curl_client_write() */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Timers */
|
||||||
|
typedef enum {
|
||||||
|
EXPIRE_100_TIMEOUT,
|
||||||
|
EXPIRE_ASYNC_NAME,
|
||||||
|
EXPIRE_CONNECTTIMEOUT,
|
||||||
|
EXPIRE_DNS_PER_NAME,
|
||||||
|
EXPIRE_HAPPY_EYEBALLS,
|
||||||
|
EXPIRE_MULTI_PENDING,
|
||||||
|
EXPIRE_RUN_NOW,
|
||||||
|
EXPIRE_SPEEDCHECK,
|
||||||
|
EXPIRE_TIMEOUT,
|
||||||
|
EXPIRE_TOOFAST,
|
||||||
|
EXPIRE_LAST /* not an actual timer, used as a marker only */
|
||||||
|
} expire_id;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One instance for each timeout an easy handle can set.
|
||||||
|
*/
|
||||||
|
struct time_node {
|
||||||
|
struct curl_llist_element list;
|
||||||
|
struct timeval time;
|
||||||
|
expire_id eid;
|
||||||
|
};
|
||||||
|
|
||||||
struct UrlState {
|
struct UrlState {
|
||||||
|
|
||||||
/* Points to the connection cache */
|
/* Points to the connection cache */
|
||||||
@ -1382,6 +1406,7 @@ struct UrlState {
|
|||||||
struct timeval expiretime; /* set this with Curl_expire() only */
|
struct timeval expiretime; /* set this with Curl_expire() only */
|
||||||
struct Curl_tree timenode; /* for the splay stuff */
|
struct Curl_tree timenode; /* for the splay stuff */
|
||||||
struct curl_llist timeoutlist; /* list of pending timeouts */
|
struct curl_llist timeoutlist; /* list of pending timeouts */
|
||||||
|
struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */
|
||||||
|
|
||||||
/* a place to store the most recently set FTP entrypath */
|
/* a place to store the most recently set FTP entrypath */
|
||||||
char *most_recent_ftp_entrypath;
|
char *most_recent_ftp_entrypath;
|
||||||
|
Loading…
Reference in New Issue
Block a user