mirror of
https://github.com/curl/curl.git
synced 2026-08-04 07:20:01 +03:00
llist: replace Curl_llist_alloc with Curl_llist_init
No longer allocate the curl_llist head struct for lists separately. Removes 17 (15%) tiny allocations in a normal "curl localhost" invoke. closes #1381
This commit is contained in:
parent
a68ca63d73
commit
e60fe20fdf
18 changed files with 214 additions and 310 deletions
102
lib/multi.c
102
lib/multi.c
|
|
@ -280,7 +280,7 @@ static int sh_init(struct curl_hash *hash, int hashsize)
|
|||
static CURLMcode multi_addmsg(struct Curl_multi *multi,
|
||||
struct Curl_message *msg)
|
||||
{
|
||||
if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
|
||||
if(!Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg))
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
return CURLM_OK;
|
||||
|
|
@ -316,13 +316,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
|||
if(Curl_conncache_init(&multi->conn_cache, chashsize))
|
||||
goto error;
|
||||
|
||||
multi->msglist = Curl_llist_alloc(multi_freeamsg);
|
||||
if(!multi->msglist)
|
||||
goto error;
|
||||
|
||||
multi->pending = Curl_llist_alloc(multi_freeamsg);
|
||||
if(!multi->pending)
|
||||
goto error;
|
||||
Curl_llist_init(&multi->msglist, multi_freeamsg);
|
||||
Curl_llist_init(&multi->pending, multi_freeamsg);
|
||||
|
||||
/* allocate a new easy handle to use when closing cached connections */
|
||||
multi->closure_handle = curl_easy_init();
|
||||
|
|
@ -345,8 +340,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
|||
Curl_conncache_destroy(&multi->conn_cache);
|
||||
Curl_close(multi->closure_handle);
|
||||
multi->closure_handle = NULL;
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
Curl_llist_destroy(multi->pending, NULL);
|
||||
Curl_llist_destroy(&multi->msglist, NULL);
|
||||
Curl_llist_destroy(&multi->pending, NULL);
|
||||
|
||||
free(multi);
|
||||
return NULL;
|
||||
|
|
@ -361,8 +356,6 @@ struct Curl_multi *curl_multi_init(void)
|
|||
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct curl_llist *timeoutlist;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
|
@ -376,10 +369,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||
if(data->multi)
|
||||
return CURLM_ADDED_ALREADY;
|
||||
|
||||
/* Allocate and initialize timeout list for easy handle */
|
||||
timeoutlist = Curl_llist_alloc(multi_freetimeout);
|
||||
if(!timeoutlist)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
/* Initialize timeout list for this handle */
|
||||
Curl_llist_init(&data->state.timeoutlist, multi_freetimeout);
|
||||
|
||||
/*
|
||||
* No failure allowed in this function beyond this point. And no
|
||||
|
|
@ -388,10 +379,6 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||
* function no matter what.
|
||||
*/
|
||||
|
||||
/* Make easy handle use timeout list initialized above */
|
||||
data->state.timeoutlist = timeoutlist;
|
||||
timeoutlist = NULL;
|
||||
|
||||
/* set the easy handle */
|
||||
multistate(data, CURLM_STATE_INIT);
|
||||
|
||||
|
|
@ -580,7 +567,7 @@ static CURLcode multi_done(struct connectdata **connp,
|
|||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||
if(conn->send_pipe.size + conn->recv_pipe.size != 0 &&
|
||||
!data->set.reuse_forbid &&
|
||||
!conn->bits.close) {
|
||||
/* Stop if pipeline is not empty and we do not have to close
|
||||
|
|
@ -741,10 +728,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
|||
|
||||
/* destroy the timeout list that is held in the easy handle, do this *after*
|
||||
multi_done() as that may actually call Curl_expire that uses this */
|
||||
if(data->state.timeoutlist) {
|
||||
Curl_llist_destroy(data->state.timeoutlist, NULL);
|
||||
data->state.timeoutlist = NULL;
|
||||
}
|
||||
Curl_llist_destroy(&data->state.timeoutlist, NULL);
|
||||
|
||||
/* as this was using a shared connection cache we clear the pointer to that
|
||||
since we're not part of that multi handle anymore */
|
||||
|
|
@ -767,11 +751,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
|||
/* make sure there's no pending message in the queue sent from this easy
|
||||
handle */
|
||||
|
||||
for(e = multi->msglist->head; e; e = e->next) {
|
||||
for(e = multi->msglist.head; e; e = e->next) {
|
||||
struct Curl_message *msg = e->ptr;
|
||||
|
||||
if(msg->extmsg.easy_handle == easy) {
|
||||
Curl_llist_remove(multi->msglist, e, NULL);
|
||||
Curl_llist_remove(&multi->msglist, e, NULL);
|
||||
/* there can only be one from this specific handle */
|
||||
break;
|
||||
}
|
||||
|
|
@ -1448,7 +1432,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
multistate(data, CURLM_STATE_CONNECT_PEND);
|
||||
|
||||
/* add this handle to the list of connect-pending handles */
|
||||
if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
|
||||
if(!Curl_llist_insert_next(&multi->pending, multi->pending.tail, data))
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
result = CURLE_OK;
|
||||
|
|
@ -1954,11 +1938,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
Curl_posttransfer(data);
|
||||
|
||||
/* we're no longer receiving */
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||
|
||||
/* expire the new receiving pipeline head */
|
||||
if(data->easy_conn->recv_pipe->head)
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
|
||||
if(data->easy_conn->recv_pipe.head)
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe.head->ptr, 0);
|
||||
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
|
|
@ -2023,7 +2007,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
CURLcode res;
|
||||
|
||||
/* Remove ourselves from the receive pipeline, if we are there. */
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
|
||||
|
|
@ -2099,8 +2083,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
/* if this has a connection, unsubscribe from the pipelines */
|
||||
Curl_pipeline_leave_write(data->easy_conn);
|
||||
Curl_pipeline_leave_read(data->easy_conn);
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||
|
||||
if(stream_error) {
|
||||
/* Don't attempt to send data over a connection that timed out */
|
||||
|
|
@ -2255,8 +2239,8 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
|||
|
||||
Curl_hash_destroy(&multi->sockhash);
|
||||
Curl_conncache_destroy(&multi->conn_cache);
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
Curl_llist_destroy(multi->pending, NULL);
|
||||
Curl_llist_destroy(&multi->msglist, NULL);
|
||||
Curl_llist_destroy(&multi->pending, NULL);
|
||||
|
||||
/* remove all easy handles */
|
||||
data = multi->easyp;
|
||||
|
|
@ -2307,19 +2291,19 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
|
|||
|
||||
*msgs_in_queue = 0; /* default to none */
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
|
||||
if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(&multi->msglist)) {
|
||||
/* there is one or more messages in the list */
|
||||
struct curl_llist_element *e;
|
||||
|
||||
/* extract the head of the list to return */
|
||||
e = multi->msglist->head;
|
||||
e = multi->msglist.head;
|
||||
|
||||
msg = e->ptr;
|
||||
|
||||
/* remove the extracted entry */
|
||||
Curl_llist_remove(multi->msglist, e, NULL);
|
||||
Curl_llist_remove(&multi->msglist, e, NULL);
|
||||
|
||||
*msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
|
||||
*msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
|
||||
|
||||
return &msg->extmsg;
|
||||
}
|
||||
|
|
@ -2418,7 +2402,7 @@ static void singlesocket(struct Curl_multi *multi,
|
|||
removed. */
|
||||
struct connectdata *easy_conn = data->easy_conn;
|
||||
if(easy_conn) {
|
||||
if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
|
||||
if(easy_conn->recv_pipe.size > 1) {
|
||||
/* the handle should not be removed from the pipe yet */
|
||||
remove_sock_from_hash = FALSE;
|
||||
|
||||
|
|
@ -2427,12 +2411,12 @@ static void singlesocket(struct Curl_multi *multi,
|
|||
isn't already) */
|
||||
if(entry->easy == data) {
|
||||
if(Curl_recvpipe_head(data, easy_conn))
|
||||
entry->easy = easy_conn->recv_pipe->head->next->ptr;
|
||||
entry->easy = easy_conn->recv_pipe.head->next->ptr;
|
||||
else
|
||||
entry->easy = easy_conn->recv_pipe->head->ptr;
|
||||
entry->easy = easy_conn->recv_pipe.head->ptr;
|
||||
}
|
||||
}
|
||||
if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
|
||||
if(easy_conn->send_pipe.size > 1) {
|
||||
/* the handle should not be removed from the pipe yet */
|
||||
remove_sock_from_hash = FALSE;
|
||||
|
||||
|
|
@ -2441,9 +2425,9 @@ static void singlesocket(struct Curl_multi *multi,
|
|||
isn't already) */
|
||||
if(entry->easy == data) {
|
||||
if(Curl_sendpipe_head(data, easy_conn))
|
||||
entry->easy = easy_conn->send_pipe->head->next->ptr;
|
||||
entry->easy = easy_conn->send_pipe.head->next->ptr;
|
||||
else
|
||||
entry->easy = easy_conn->send_pipe->head->ptr;
|
||||
entry->easy = easy_conn->send_pipe.head->ptr;
|
||||
}
|
||||
}
|
||||
/* Don't worry about overwriting recv_pipe head with send_pipe_head,
|
||||
|
|
@ -2518,7 +2502,7 @@ static CURLMcode add_next_timeout(struct timeval now,
|
|||
struct Curl_easy *d)
|
||||
{
|
||||
struct timeval *tv = &d->state.expiretime;
|
||||
struct curl_llist *list = d->state.timeoutlist;
|
||||
struct curl_llist *list = &d->state.timeoutlist;
|
||||
struct curl_llist_element *e;
|
||||
|
||||
/* move over the timeout list for this specific handle and remove all
|
||||
|
|
@ -2609,13 +2593,11 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||
head. If we should read from the socket, take the recv_pipe head. */
|
||||
if(data->easy_conn) {
|
||||
if((ev_bitmask & CURL_POLL_OUT) &&
|
||||
data->easy_conn->send_pipe &&
|
||||
data->easy_conn->send_pipe->head)
|
||||
data = data->easy_conn->send_pipe->head->ptr;
|
||||
data->easy_conn->send_pipe.head)
|
||||
data = data->easy_conn->send_pipe.head->ptr;
|
||||
else if((ev_bitmask & CURL_POLL_IN) &&
|
||||
data->easy_conn->recv_pipe &&
|
||||
data->easy_conn->recv_pipe->head)
|
||||
data = data->easy_conn->recv_pipe->head->ptr;
|
||||
data->easy_conn->recv_pipe.head)
|
||||
data = data->easy_conn->recv_pipe.head->ptr;
|
||||
}
|
||||
|
||||
if(data->easy_conn &&
|
||||
|
|
@ -2967,13 +2949,13 @@ void Curl_expire(struct Curl_easy *data, time_t milli)
|
|||
if(diff > 0) {
|
||||
/* the new expire time was later so just add it to the queue
|
||||
and get out */
|
||||
multi_addtimeout(data->state.timeoutlist, &set);
|
||||
multi_addtimeout(&data->state.timeoutlist, &set);
|
||||
return;
|
||||
}
|
||||
|
||||
/* the new time is newer than the presently set one, so add the current
|
||||
to the queue and update the head */
|
||||
multi_addtimeout(data->state.timeoutlist, nowp);
|
||||
multi_addtimeout(&data->state.timeoutlist, nowp);
|
||||
|
||||
/* Since this is an updated time, we must remove the previous entry from
|
||||
the splay tree first and then re-add the new value */
|
||||
|
|
@ -3050,7 +3032,7 @@ void Curl_expire_clear(struct Curl_easy *data)
|
|||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
the splay tree */
|
||||
struct curl_llist *list = data->state.timeoutlist;
|
||||
struct curl_llist *list = &data->state.timeoutlist;
|
||||
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
|
|
@ -3110,17 +3092,17 @@ curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
|
|||
|
||||
struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
|
||||
{
|
||||
return multi->pipelining_site_bl;
|
||||
return &multi->pipelining_site_bl;
|
||||
}
|
||||
|
||||
struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
|
||||
{
|
||||
return multi->pipelining_server_bl;
|
||||
return &multi->pipelining_server_bl;
|
||||
}
|
||||
|
||||
void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
{
|
||||
struct curl_llist_element *e = multi->pending->head;
|
||||
struct curl_llist_element *e = multi->pending.head;
|
||||
|
||||
while(e) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
|
|
@ -3130,7 +3112,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
|||
multistate(data, CURLM_STATE_CONNECT);
|
||||
|
||||
/* Remove this node from the list */
|
||||
Curl_llist_remove(multi->pending, e, NULL);
|
||||
Curl_llist_remove(&multi->pending, e, NULL);
|
||||
|
||||
/* Make sure that the handle will be processed soonish. */
|
||||
Curl_expire_latest(data, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue