From e60fe20fdf94e829ba5fce33f7a9d6c281149f7d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 3 Apr 2017 10:32:43 +0200 Subject: [PATCH] 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 --- lib/conncache.c | 22 ++++----- lib/conncache.h | 4 +- lib/ftp.c | 15 +++--- lib/ftplistparser.c | 4 +- lib/hash.c | 30 ++++-------- lib/hash.h | 4 +- lib/llist.c | 22 ++------- lib/llist.h | 4 +- lib/multi.c | 102 +++++++++++++++++----------------------- lib/multihandle.h | 16 +++---- lib/pipeline.c | 81 +++++++++++++------------------- lib/pipeline.h | 6 +-- lib/transfer.c | 3 +- lib/url.c | 67 ++++++++++---------------- lib/urldata.h | 10 ++-- lib/wildcard.c | 18 +++---- lib/wildcard.h | 9 ++-- tests/unit/unit1300.c | 107 ++++++++++++++++++++---------------------- 18 files changed, 214 insertions(+), 310 deletions(-) diff --git a/lib/conncache.c b/lib/conncache.c index 7143ff83a..0590ec631 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -56,11 +56,7 @@ static CURLcode bundle_create(struct Curl_easy *data, (*cb_ptr)->num_connections = 0; (*cb_ptr)->multiuse = BUNDLE_UNKNOWN; - (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor); - if(!(*cb_ptr)->conn_list) { - Curl_safefree(*cb_ptr); - return CURLE_OUT_OF_MEMORY; - } + Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor); return CURLE_OK; } @@ -69,10 +65,8 @@ static void bundle_destroy(struct connectbundle *cb_ptr) if(!cb_ptr) return; - if(cb_ptr->conn_list) { - Curl_llist_destroy(cb_ptr->conn_list, NULL); - cb_ptr->conn_list = NULL; - } + Curl_llist_destroy(&cb_ptr->conn_list, NULL); + free(cb_ptr); } @@ -80,7 +74,7 @@ static void bundle_destroy(struct connectbundle *cb_ptr) static CURLcode bundle_add_conn(struct connectbundle *cb_ptr, struct connectdata *conn) { - if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn)) + if(!Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn)) return CURLE_OUT_OF_MEMORY; conn->bundle = cb_ptr; @@ -95,10 +89,10 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr, { struct curl_llist_element *curr; - curr = cb_ptr->conn_list->head; + curr = cb_ptr->conn_list.head; while(curr) { if(curr->ptr == conn) { - Curl_llist_remove(cb_ptr->conn_list, curr, NULL); + Curl_llist_remove(&cb_ptr->conn_list, curr, NULL); cb_ptr->num_connections--; conn->bundle = NULL; return 1; /* we removed a handle */ @@ -289,7 +283,7 @@ void Curl_conncache_foreach(struct conncache *connc, bundle = he->ptr; he = Curl_hash_next_element(&iter); - curr = bundle->conn_list->head; + curr = bundle->conn_list.head; while(curr) { /* Yes, we need to update curr before calling func(), because func() might decide to remove the connection */ @@ -318,7 +312,7 @@ Curl_conncache_find_first_connection(struct conncache *connc) struct curl_llist_element *curr; bundle = he->ptr; - curr = bundle->conn_list->head; + curr = bundle->conn_list.head; if(curr) { return curr->ptr; } diff --git a/lib/conncache.h b/lib/conncache.h index b1dadf990..f976cfdb4 100644 --- a/lib/conncache.h +++ b/lib/conncache.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2015, Daniel Stenberg, , et al. + * Copyright (C) 2015 - 2017, Daniel Stenberg, , et al. * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, * * This software is licensed as described in the file COPYING, which @@ -38,7 +38,7 @@ struct conncache { struct connectbundle { int multiuse; /* supports multi-use */ size_t num_connections; /* Number of connections in the bundle */ - struct curl_llist *conn_list; /* The connectdata members of the bundle */ + struct curl_llist conn_list; /* The connectdata members of the bundle */ }; int Curl_conncache_init(struct conncache *, int size); diff --git a/lib/ftp.c b/lib/ftp.c index 1001d4fb1..059bd2ac0 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -3900,7 +3900,7 @@ static CURLcode wc_statemach(struct connectdata *conn) wildcard->state = CURLWC_CLEAN; return wc_statemach(conn); } - if(wildcard->filelist->size == 0) { + if(wildcard->filelist.size == 0) { /* no corresponding file */ wildcard->state = CURLWC_CLEAN; return CURLE_REMOTE_FILE_NOT_FOUND; @@ -3911,7 +3911,7 @@ static CURLcode wc_statemach(struct connectdata *conn) case CURLWC_DOWNLOADING: { /* filelist has at least one file, lets get first one */ struct ftp_conn *ftpc = &conn->proto.ftpc; - struct curl_fileinfo *finfo = wildcard->filelist->head->ptr; + struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); if(!tmp_path) @@ -3926,7 +3926,7 @@ static CURLcode wc_statemach(struct connectdata *conn) infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); if(conn->data->set.chunk_bgn) { long userresponse = conn->data->set.chunk_bgn( - finfo, wildcard->customptr, (int)wildcard->filelist->size); + finfo, wildcard->customptr, (int)wildcard->filelist.size); switch(userresponse) { case CURL_CHUNK_BGN_FUNC_SKIP: infof(conn->data, "Wildcard - \"%s\" skipped by user\n", @@ -3951,9 +3951,9 @@ static CURLcode wc_statemach(struct connectdata *conn) return result; /* we don't need the Curl_fileinfo of first file anymore */ - Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL); + Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); - if(wildcard->filelist->size == 0) { /* remains only one file to down. */ + if(wildcard->filelist.size == 0) { /* remains only one file to down. */ wildcard->state = CURLWC_CLEAN; /* after that will be ftp_do called once again and no transfer will be done because of CURLWC_CLEAN state */ @@ -3964,8 +3964,8 @@ static CURLcode wc_statemach(struct connectdata *conn) case CURLWC_SKIP: { if(conn->data->set.chunk_end) conn->data->set.chunk_end(conn->data->wildcard.customptr); - Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL); - wildcard->state = (wildcard->filelist->size == 0) ? + Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + wildcard->state = (wildcard->filelist.size == 0) ? CURLWC_CLEAN : CURLWC_DOWNLOADING; return wc_statemach(conn); } @@ -3981,6 +3981,7 @@ static CURLcode wc_statemach(struct connectdata *conn) case CURLWC_DONE: case CURLWC_ERROR: + case CURLWC_CLEAR: break; } diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c index 0c2e3e1a4..bc186805f 100644 --- a/lib/ftplistparser.c +++ b/lib/ftplistparser.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -280,7 +280,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, curl_fnmatch_callback compare; struct WildcardData *wc = &conn->data->wildcard; struct ftp_wc_tmpdata *tmpdata = wc->tmp; - struct curl_llist *llist = wc->filelist; + struct curl_llist *llist = &wc->filelist; struct ftp_parselist_data *parser = tmpdata->parser; bool add = TRUE; diff --git a/lib/hash.c b/lib/hash.c index c26be0118..c76bc1d95 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -74,21 +74,10 @@ Curl_hash_init(struct curl_hash *h, h->size = 0; h->slots = slots; - h->table = malloc(slots * sizeof(struct curl_llist *)); + h->table = malloc(slots * sizeof(struct curl_llist)); if(h->table) { - for(i = 0; i < slots; ++i) { - h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); - if(!h->table[i]) { - while(i--) { - Curl_llist_destroy(h->table[i], NULL); - h->table[i] = NULL; - } - free(h->table); - h->table = NULL; - h->slots = 0; - return 1; /* failure */ - } - } + for(i = 0; i < slots; ++i) + Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor); return 0; /* fine */ } h->slots = 0; @@ -119,7 +108,7 @@ mk_hash_element(const void *key, size_t key_len, const void *p) return he; } -#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)] +#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)] /* Insert the data in the hash. If there already was a match in the hash, * that data is replaced. @@ -241,8 +230,7 @@ Curl_hash_destroy(struct curl_hash *h) int i; for(i = 0; i < h->slots; ++i) { - Curl_llist_destroy(h->table[i], (void *) h); - h->table[i] = NULL; + Curl_llist_destroy(&h->table[i], (void *) h); } Curl_safefree(h->table); @@ -274,7 +262,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, return; for(i = 0; i < h->slots; ++i) { - list = h->table[i]; + list = &h->table[i]; le = list->head; /* get first list entry */ while(le) { struct curl_hash_element *he = le->ptr; @@ -333,8 +321,8 @@ Curl_hash_next_element(struct curl_hash_iterator *iter) /* If we have reached the end of the list, find the next one */ if(!iter->current_element) { for(i = iter->slot_index;i < h->slots;i++) { - if(h->table[i]->head) { - iter->current_element = h->table[i]->head; + if(h->table[i].head) { + iter->current_element = h->table[i].head; iter->slot_index = i+1; break; } diff --git a/lib/hash.h b/lib/hash.h index a5a6cac72..5929fc264 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,7 +44,7 @@ typedef size_t (*comp_function) (void *key1, typedef void (*curl_hash_dtor)(void *); struct curl_hash { - struct curl_llist **table; + struct curl_llist *table; /* Hash function to be used for this hash table */ hash_function hash_func; diff --git a/lib/llist.c b/lib/llist.c index 482aaa041..b8836bbcc 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -33,8 +33,8 @@ /* * @unittest: 1300 */ -static void -llist_init(struct curl_llist *l, curl_llist_dtor dtor) +void +Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor) { l->size = 0; l->dtor = dtor; @@ -42,20 +42,6 @@ llist_init(struct curl_llist *l, curl_llist_dtor dtor) l->tail = NULL; } -struct curl_llist * -Curl_llist_alloc(curl_llist_dtor dtor) -{ - struct curl_llist *list; - - list = malloc(sizeof(struct curl_llist)); - if(!list) - return NULL; - - llist_init(list, dtor); - - return list; -} - /* * Curl_llist_insert_next() * @@ -149,8 +135,6 @@ Curl_llist_destroy(struct curl_llist *list, void *user) if(list) { while(list->size > 0) Curl_llist_remove(list, list->tail, user); - - free(list); } } diff --git a/lib/llist.h b/lib/llist.h index 39ff408ee..47935ad1f 100644 --- a/lib/llist.h +++ b/lib/llist.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -43,7 +43,7 @@ struct curl_llist { size_t size; }; -struct curl_llist *Curl_llist_alloc(curl_llist_dtor); +void Curl_llist_init(struct curl_llist *, curl_llist_dtor); int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *, const void *); int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *, diff --git a/lib/multi.c b/lib/multi.c index 47101376a..46286b77b 100644 --- a/lib/multi.c +++ b/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); diff --git a/lib/multihandle.h b/lib/multihandle.h index 0b78de943..915b857fe 100644 --- a/lib/multihandle.h +++ b/lib/multihandle.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -80,10 +80,10 @@ struct Curl_multi { int num_alive; /* amount of easy handles that are added but have not yet reached COMPLETE state */ - struct curl_llist *msglist; /* a list of messages from completed transfers */ + struct curl_llist msglist; /* a list of messages from completed transfers */ - struct curl_llist *pending; /* Curl_easys that are in the - CURLM_STATE_CONNECT_PEND state */ + struct curl_llist pending; /* Curl_easys that are in the + CURLM_STATE_CONNECT_PEND state */ /* callback function and user data pointer for the *socket() API */ curl_socket_callback socket_cb; @@ -138,11 +138,11 @@ struct Curl_multi { bigger than this is not considered for pipelining */ - struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted - from pipelining */ + struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted + from pipelining */ - struct curl_llist *pipelining_server_bl; /* List of server types that are - blacklisted from pipelining */ + struct curl_llist pipelining_server_bl; /* List of server types that are + blacklisted from pipelining */ /* timer callback and user data pointer for the *socket() API */ curl_multi_timer_callback timer_cb; diff --git a/lib/pipeline.c b/lib/pipeline.c index 40a5e82d8..4a14fddfe 100644 --- a/lib/pipeline.c +++ b/lib/pipeline.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2013, Linus Nielsen Feltzing, - * Copyright (C) 2013-2016, Daniel Stenberg, , et al. + * Copyright (C) 2013 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -69,8 +69,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data, curl_off_t recv_size = -2; /* Make it easy to spot in the log */ /* Find the head of the recv pipe, if any */ - if(conn->recv_pipe && conn->recv_pipe->head) { - struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr; + if(conn->recv_pipe.head) { + struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr; recv_size = recv_handle->req.size; @@ -103,18 +103,18 @@ static CURLcode addHandleToPipeline(struct Curl_easy *data, CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle, struct connectdata *conn) { - struct curl_llist_element *sendhead = conn->send_pipe->head; + struct curl_llist_element *sendhead = conn->send_pipe.head; struct curl_llist *pipeline; CURLcode result; - pipeline = conn->send_pipe; + pipeline = &conn->send_pipe; result = addHandleToPipeline(handle, pipeline); - 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 */ Curl_pipeline_leave_write(conn); /* not in use yet */ - Curl_expire(conn->send_pipe->head->ptr, 0); + Curl_expire(conn->send_pipe.head->ptr, 0); } #if 0 /* enable for pipeline debugging */ @@ -135,21 +135,21 @@ void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle, { struct curl_llist_element *curr; - curr = conn->send_pipe->head; + curr = conn->send_pipe.head; while(curr) { if(curr->ptr == handle) { - Curl_llist_move(conn->send_pipe, curr, - conn->recv_pipe, conn->recv_pipe->tail); + Curl_llist_move(&conn->send_pipe, curr, + &conn->recv_pipe, conn->recv_pipe.tail); - if(conn->send_pipe->head) { + if(conn->send_pipe.head) { /* Since there's a new easy handle at the start of the send pipeline, set its timeout value to 1ms to make it trigger instantly */ Curl_pipeline_leave_write(conn); /* not used now */ #ifdef DEBUGBUILD infof(conn->data, "%p is at send pipe head B!\n", - (void *)conn->send_pipe->head->ptr); + (void *)conn->send_pipe.head->ptr); #endif - Curl_expire(conn->send_pipe->head->ptr, 0); + Curl_expire(conn->send_pipe.head->ptr, 0); } /* The receiver's list is not really interesting here since either this @@ -191,15 +191,14 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle, } CURLMcode Curl_pipeline_set_site_blacklist(char **sites, - struct curl_llist **list_ptr) + struct curl_llist *list) { - struct curl_llist *old_list = *list_ptr; - struct curl_llist *new_list = NULL; + /* Free the old list */ + if(list->size) + Curl_llist_destroy(list, NULL); if(sites) { - new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor); - if(!new_list) - return CURLM_OUT_OF_MEMORY; + Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor); /* Parse the URLs and populate the list */ while(*sites) { @@ -209,14 +208,14 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites, hostname = strdup(*sites); if(!hostname) { - Curl_llist_destroy(new_list, NULL); + Curl_llist_destroy(list, NULL); return CURLM_OUT_OF_MEMORY; } entry = malloc(sizeof(struct site_blacklist_entry)); if(!entry) { free(hostname); - Curl_llist_destroy(new_list, NULL); + Curl_llist_destroy(list, NULL); return CURLM_OUT_OF_MEMORY; } @@ -233,9 +232,9 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites, entry->hostname = hostname; - if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) { + if(!Curl_llist_insert_next(list, list->tail, entry)) { site_blacklist_llist_dtor(NULL, entry); - Curl_llist_destroy(new_list, NULL); + Curl_llist_destroy(list, NULL); return CURLM_OUT_OF_MEMORY; } @@ -243,14 +242,6 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites, } } - /* Free the old list */ - if(old_list) { - Curl_llist_destroy(old_list, NULL); - } - - /* This might be NULL if sites == NULL, i.e the blacklist is cleared */ - *list_ptr = new_list; - return CURLM_OK; } @@ -284,15 +275,14 @@ bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle, } CURLMcode Curl_pipeline_set_server_blacklist(char **servers, - struct curl_llist **list_ptr) + struct curl_llist *list) { - struct curl_llist *old_list = *list_ptr; - struct curl_llist *new_list = NULL; + /* Free the old list */ + if(list->size) + Curl_llist_destroy(list, NULL); if(servers) { - new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor); - if(!new_list) - return CURLM_OUT_OF_MEMORY; + Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor); /* Parse the URLs and populate the list */ while(*servers) { @@ -300,12 +290,12 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers, server_name = strdup(*servers); if(!server_name) { - Curl_llist_destroy(new_list, NULL); + Curl_llist_destroy(list, NULL); return CURLM_OUT_OF_MEMORY; } - if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) { - Curl_llist_destroy(new_list, NULL); + if(!Curl_llist_insert_next(list, list->tail, server_name)) { + Curl_llist_destroy(list, NULL); Curl_safefree(server_name); return CURLM_OUT_OF_MEMORY; } @@ -314,13 +304,6 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers, } } - /* Free the old list */ - if(old_list) { - Curl_llist_destroy(old_list, NULL); - } - - /* This might be NULL if sites == NULL, i.e the blacklist is cleared */ - *list_ptr = new_list; return CURLM_OK; } @@ -340,14 +323,14 @@ static bool pipe_head(struct Curl_easy *data, bool Curl_recvpipe_head(struct Curl_easy *data, struct connectdata *conn) { - return pipe_head(data, conn->recv_pipe); + return pipe_head(data, &conn->recv_pipe); } /* returns TRUE if the given handle is head of the send pipe */ bool Curl_sendpipe_head(struct Curl_easy *data, struct connectdata *conn) { - return pipe_head(data, conn->send_pipe); + return pipe_head(data, &conn->send_pipe); } diff --git a/lib/pipeline.h b/lib/pipeline.h index a64f71025..413ba31a0 100644 --- a/lib/pipeline.h +++ b/lib/pipeline.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2015, Daniel Stenberg, , et al. + * Copyright (C) 2015 - 2017, Daniel Stenberg, , et al. * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, * * This software is licensed as described in the file COPYING, which @@ -34,13 +34,13 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle, struct connectdata *conn); CURLMcode Curl_pipeline_set_site_blacklist(char **sites, - struct curl_llist **list_ptr); + struct curl_llist *list_ptr); bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle, char *server_name); CURLMcode Curl_pipeline_set_server_blacklist(char **servers, - struct curl_llist **list_ptr); + struct curl_llist *list_ptr); bool Curl_pipeline_checkget_write(struct Curl_easy *data, struct connectdata *conn); diff --git a/lib/transfer.c b/lib/transfer.c index 38a049956..1f6d26d7f 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1356,13 +1356,12 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) if(data->set.wildcardmatch) { struct WildcardData *wc = &data->wildcard; - if(!wc->filelist) { + if(wc->state < CURLWC_INIT) { result = Curl_wildcard_init(wc); /* init wildcard structures */ if(result) return CURLE_OUT_OF_MEMORY; } } - } return result; diff --git a/lib/url.c b/lib/url.c index 01e02de54..33ba783fc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -411,10 +411,7 @@ CURLcode Curl_close(struct Curl_easy *data) /* Destroy the timeout list that is held in the easy handle. It is /normally/ done by curl_multi_remove_handle() but this is "just in case" */ - if(data->state.timeoutlist) { - Curl_llist_destroy(data->state.timeoutlist, NULL); - data->state.timeoutlist = NULL; - } + Curl_llist_destroy(&data->state.timeoutlist, NULL); data->magic = 0; /* force a clear AFTER the possibly enforced removal from the multi handle, since that function uses the magic @@ -672,9 +669,6 @@ CURLcode Curl_open(struct Curl_easy **curl) data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ - - data->wildcard.state = CURLWC_INIT; - data->wildcard.filelist = NULL; data->set.fnmatch = ZERO_NULL; data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ @@ -3001,11 +2995,8 @@ static void conn_free(struct connectdata *conn) conn_reset_all_postponed_data(conn); - Curl_llist_destroy(conn->send_pipe, NULL); - Curl_llist_destroy(conn->recv_pipe, NULL); - - conn->send_pipe = NULL; - conn->recv_pipe = NULL; + Curl_llist_destroy(&conn->send_pipe, NULL); + Curl_llist_destroy(&conn->recv_pipe, NULL); Curl_safefree(conn->localdev); Curl_free_primary_ssl_config(&conn->ssl_config); @@ -3045,9 +3036,9 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) * are other users of it */ if(!conn->bits.close && - (conn->send_pipe->size + conn->recv_pipe->size)) { + (conn->send_pipe.size + conn->recv_pipe.size)) { DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n", - conn->send_pipe->size + conn->recv_pipe->size)); + conn->send_pipe.size + conn->recv_pipe.size)); return CURLE_OK; } @@ -3080,8 +3071,8 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) /* Indicate to all handles on the pipe that we're dead */ if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) { - signalPipeClose(conn->send_pipe, TRUE); - signalPipeClose(conn->recv_pipe, TRUE); + signalPipeClose(&conn->send_pipe, TRUE); + signalPipeClose(&conn->recv_pipe, TRUE); } conn_free(conn); @@ -3186,9 +3177,9 @@ void Curl_getoff_all_pipelines(struct Curl_easy *data, bool send_head = (conn->writechannel_inuse && Curl_sendpipe_head(data, conn)); - if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head) + if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head) Curl_pipeline_leave_read(conn); - if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head) + if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head) Curl_pipeline_leave_write(conn); } @@ -3249,7 +3240,7 @@ Curl_oldest_idle_connection(struct Curl_easy *data) bundle = he->ptr; - curr = bundle->conn_list->head; + curr = bundle->conn_list.head; while(curr) { conn = curr->ptr; @@ -3306,7 +3297,7 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy *data, now = Curl_tvnow(); - curr = bundle->conn_list->head; + curr = bundle->conn_list.head; while(curr) { conn = curr->ptr; @@ -3334,7 +3325,7 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy *data, static bool disconnect_if_dead(struct connectdata *conn, struct Curl_easy *data) { - size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size; + size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size; if(!pipeLen && !conn->inuse) { /* The check for a dead socket makes sense only if there are no handles in pipeline and the connection isn't already marked in @@ -3481,7 +3472,7 @@ ConnectionExists(struct Curl_easy *data, } } - curr = bundle->conn_list->head; + curr = bundle->conn_list.head; while(curr) { bool match = FALSE; size_t pipeLen; @@ -3496,7 +3487,7 @@ ConnectionExists(struct Curl_easy *data, if(disconnect_if_dead(check, data)) continue; - pipeLen = check->send_pipe->size + check->recv_pipe->size; + pipeLen = check->send_pipe.size + check->recv_pipe.size; if(canPipeline) { if(check->bits.protoconnstart && check->bits.close) @@ -3504,8 +3495,8 @@ ConnectionExists(struct Curl_easy *data, if(!check->bits.multiplex) { /* If not multiplexing, make sure the pipe has only GET requests */ - struct Curl_easy* sh = gethandleathead(check->send_pipe); - struct Curl_easy* rh = gethandleathead(check->recv_pipe); + struct Curl_easy* sh = gethandleathead(&check->send_pipe); + struct Curl_easy* rh = gethandleathead(&check->recv_pipe); if(sh) { if(!IsPipeliningPossible(sh, check)) continue; @@ -3543,7 +3534,7 @@ ConnectionExists(struct Curl_easy *data, infof(data, "Connection #%ld isn't open enough, can't reuse\n", check->connection_id); #ifdef DEBUGBUILD - if(check->recv_pipe->size > 0) { + if(check->recv_pipe.size > 0) { infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", check->connection_id); @@ -4217,10 +4208,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) } /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe) - goto error; + Curl_llist_init(&conn->send_pipe, (curl_llist_dtor) llist_dtor); + Curl_llist_init(&conn->recv_pipe, (curl_llist_dtor) llist_dtor); #ifdef HAVE_GSSAPI conn->data_prot = PROT_CLEAR; @@ -4243,11 +4232,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) return conn; error: - Curl_llist_destroy(conn->send_pipe, NULL); - Curl_llist_destroy(conn->recv_pipe, NULL); - - conn->send_pipe = NULL; - conn->recv_pipe = NULL; + Curl_llist_destroy(&conn->send_pipe, NULL); + Curl_llist_destroy(&conn->recv_pipe, NULL); free(conn->master_buffer); free(conn->localdev); @@ -6242,11 +6228,8 @@ static void reuse_conn(struct connectdata *old_conn, Curl_safefree(old_conn->socks_proxy.passwd); Curl_safefree(old_conn->localdev); - Curl_llist_destroy(old_conn->send_pipe, NULL); - Curl_llist_destroy(old_conn->recv_pipe, NULL); - - old_conn->send_pipe = NULL; - old_conn->recv_pipe = NULL; + Curl_llist_destroy(&old_conn->send_pipe, NULL); + Curl_llist_destroy(&old_conn->recv_pipe, NULL); Curl_safefree(old_conn->master_buffer); @@ -6645,7 +6628,7 @@ static CURLcode create_conn(struct Curl_easy *data, /* If we found a reusable connection, we may still want to open a new connection if we are pipelining. */ if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) { - size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size; + size_t pipelen = conn_temp->send_pipe.size + conn_temp->recv_pipe.size; if(pipelen > 0) { infof(data, "Found connection %ld, with requests in the pipe (%zu)\n", conn_temp->connection_id, pipelen); @@ -6913,7 +6896,7 @@ CURLcode Curl_connect(struct Curl_easy *data, if(!result) { /* no error */ - if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size) + if((*in_connect)->send_pipe.size || (*in_connect)->recv_pipe.size) /* pipelining */ *protocol_done = TRUE; else if(!*asyncp) { diff --git a/lib/urldata.h b/lib/urldata.h index 9b3849117..fa6d4e0fc 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1058,10 +1058,10 @@ struct connectdata { handle */ bool writechannel_inuse; /* whether the write channel is in use by an easy handle */ - struct curl_llist *send_pipe; /* List of handles waiting to - send on this pipeline */ - struct curl_llist *recv_pipe; /* List of handles waiting to read - their responses on this pipeline */ + struct curl_llist send_pipe; /* List of handles waiting to send on this + pipeline */ + struct curl_llist recv_pipe; /* List of handles waiting to read their + responses on this pipeline */ char *master_buffer; /* The master buffer allocated on-demand; used for pipelining. */ size_t read_pos; /* Current read position in the master buffer */ @@ -1374,7 +1374,7 @@ struct UrlState { #endif /* USE_OPENSSL */ struct timeval expiretime; /* set this with Curl_expire() only */ struct Curl_tree timenode; /* for the splay stuff */ - struct curl_llist *timeoutlist; /* list of pending timeouts */ + struct curl_llist timeoutlist; /* list of pending timeouts */ /* a place to store the most recently set FTP entrypath */ char *most_recent_ftp_entrypath; diff --git a/lib/wildcard.c b/lib/wildcard.c index dbbe45f6f..af45c79bd 100644 --- a/lib/wildcard.c +++ b/lib/wildcard.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,13 +32,9 @@ CURLcode Curl_wildcard_init(struct WildcardData *wc) { - DEBUGASSERT(wc->filelist == NULL); - /* now allocate only wc->filelist, everything else - will be allocated if it is needed. */ - wc->filelist = Curl_llist_alloc(Curl_fileinfo_dtor); - if(!wc->filelist) {; - return CURLE_OUT_OF_MEMORY; - } + Curl_llist_init(&wc->filelist, Curl_fileinfo_dtor); + wc->state = CURLWC_INIT; + return CURLE_OK; } @@ -54,10 +50,8 @@ void Curl_wildcard_dtor(struct WildcardData *wc) } DEBUGASSERT(wc->tmp == NULL); - if(wc->filelist) { - Curl_llist_destroy(wc->filelist, NULL); - wc->filelist = NULL; - } + Curl_llist_destroy(&wc->filelist, NULL); + free(wc->path); wc->path = NULL; diff --git a/lib/wildcard.h b/lib/wildcard.h index 7f61cd173..8a5e4b769 100644 --- a/lib/wildcard.h +++ b/lib/wildcard.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010 - 2013, Daniel Stenberg, , et al. + * Copyright (C) 2010 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,9 +24,12 @@ #include +#include "llist.h" + /* list of wildcard process states */ typedef enum { - CURLWC_INIT = 0, + CURLWC_CLEAR = 0, + CURLWC_INIT = 1, CURLWC_MATCHING, /* library is trying to get list of addresses for downloading */ CURLWC_DOWNLOADING, @@ -44,7 +47,7 @@ struct WildcardData { curl_wildcard_states state; char *path; /* path to the directory, where we trying wildcard-match */ char *pattern; /* wildcard pattern */ - struct curl_llist *filelist; /* llist with struct Curl_fileinfo */ + struct curl_llist filelist; /* llist with struct Curl_fileinfo */ void *tmp; /* pointer to protocol specific temporary data */ curl_wildcard_tmp_dtor tmp_dtor; void *customptr; /* for CURLOPT_CHUNK_DATA pointer */ diff --git a/tests/unit/unit1300.c b/tests/unit/unit1300.c index d90f7da0c..dec81e623 100644 --- a/tests/unit/unit1300.c +++ b/tests/unit/unit1300.c @@ -23,9 +23,9 @@ #include "llist.h" -static struct curl_llist *llist; +static struct curl_llist llist; -static struct curl_llist *llist_destination; +static struct curl_llist llist_destination; static void test_curl_llist_dtor(void *key, void *value) { @@ -36,22 +36,15 @@ static void test_curl_llist_dtor(void *key, void *value) static CURLcode unit_setup(void) { - llist = Curl_llist_alloc(test_curl_llist_dtor); - if(!llist) - return CURLE_OUT_OF_MEMORY; - llist_destination = Curl_llist_alloc(test_curl_llist_dtor); - if(!llist_destination) { - Curl_llist_destroy(llist, NULL); - return CURLE_OUT_OF_MEMORY; - } - + Curl_llist_init(&llist, test_curl_llist_dtor); + Curl_llist_init(&llist_destination, test_curl_llist_dtor); return CURLE_OK; } static void unit_stop(void) { - Curl_llist_destroy(llist, NULL); - Curl_llist_destroy(llist_destination, NULL); + Curl_llist_destroy(&llist, NULL); + Curl_llist_destroy(&llist_destination, NULL); } UNITTEST_START @@ -62,7 +55,7 @@ UNITTEST_START struct curl_llist_element *element_next; struct curl_llist_element *element_prev; struct curl_llist_element *to_remove; - size_t llist_size = Curl_llist_count(llist); + size_t llist_size = Curl_llist_count(&llist); int curlErrCode = 0; /** @@ -76,10 +69,10 @@ UNITTEST_START * 4: list dtor will be NULL */ - fail_unless(llist->size == 0, "list initial size should be zero"); - fail_unless(llist->head == NULL, "list head should initiate to NULL"); - fail_unless(llist->tail == NULL, "list tail should intiate to NULL"); - fail_unless(llist->dtor == test_curl_llist_dtor, + fail_unless(llist.size == 0, "list initial size should be zero"); + fail_unless(llist.head == NULL, "list head should initiate to NULL"); + fail_unless(llist.tail == NULL, "list tail should intiate to NULL"); + fail_unless(llist.dtor == test_curl_llist_dtor, "list dtor shold initiate to test_curl_llist_dtor"); /** @@ -92,15 +85,15 @@ UNITTEST_START * 3: list tail will be the same as list head */ - curlErrCode = Curl_llist_insert_next(llist, llist->head, &unusedData_case1); + curlErrCode = Curl_llist_insert_next(&llist, llist.head, &unusedData_case1); if(curlErrCode == 1) { - fail_unless(Curl_llist_count(llist) == 1, + fail_unless(Curl_llist_count(&llist) == 1, "List size should be 1 after adding a new element"); /*test that the list head data holds my unusedData */ - fail_unless(llist->head->ptr == &unusedData_case1, + fail_unless(llist.head->ptr == &unusedData_case1, "List size should be 1 after adding a new element"); /*same goes for the list tail */ - fail_unless(llist->tail == llist->head, + fail_unless(llist.tail == llist.head, "List size should be 1 after adding a new element"); /** @@ -112,12 +105,12 @@ UNITTEST_START * 2: the list tail should be our newly created element */ - curlErrCode = Curl_llist_insert_next(llist, llist->head, + curlErrCode = Curl_llist_insert_next(&llist, llist.head, &unusedData_case3); if(curlErrCode == 1) { - fail_unless(llist->head->next->ptr == &unusedData_case3, + fail_unless(llist.head->next->ptr == &unusedData_case3, "the node next to head is not getting set correctly"); - fail_unless(llist->tail->ptr == &unusedData_case3, + fail_unless(llist.tail->ptr == &unusedData_case3, "the list tail is not getting set correctly"); } else { @@ -134,13 +127,13 @@ UNITTEST_START * 2: the list tail should different from newly created element */ - curlErrCode = Curl_llist_insert_next(llist, llist->head, + curlErrCode = Curl_llist_insert_next(&llist, llist.head, &unusedData_case2); if(curlErrCode == 1) { - fail_unless(llist->head->next->ptr == &unusedData_case2, + fail_unless(llist.head->next->ptr == &unusedData_case2, "the node next to head is not getting set correctly"); /* better safe than sorry, check that the tail isn't corrupted */ - fail_unless(llist->tail->ptr != &unusedData_case2, + fail_unless(llist.tail->ptr != &unusedData_case2, "the list tail is not getting set correctly"); } else { @@ -165,19 +158,19 @@ UNITTEST_START * 3: "new" head's previous will be NULL */ - head=llist->head; - abort_unless(head, "llist->head is NULL"); + head=llist.head; + abort_unless(head, "llist.head is NULL"); element_next = head->next; - llist_size = Curl_llist_count(llist); + llist_size = Curl_llist_count(&llist); - Curl_llist_remove(llist, llist->head, NULL); + Curl_llist_remove(&llist, llist.head, NULL); - fail_unless(Curl_llist_count(llist) == (llist_size-1), + fail_unless(Curl_llist_count(&llist) == (llist_size-1), "llist size not decremented as expected"); - fail_unless(llist->head == element_next, + fail_unless(llist.head == element_next, "llist new head not modified properly"); - abort_unless(llist->head, "llist->head is NULL"); - fail_unless(llist->head->prev == NULL, + abort_unless(llist.head, "llist.head is NULL"); + fail_unless(llist.head->prev == NULL, "new head previous not set to null"); /** @@ -190,13 +183,13 @@ UNITTEST_START * 2: element->previous->next will be element->next * 3: element->next->previous will be element->previous */ - Curl_llist_insert_next(llist, llist->head, &unusedData_case3); - llist_size = Curl_llist_count(llist); - to_remove = llist->head->next; + Curl_llist_insert_next(&llist, llist.head, &unusedData_case3); + llist_size = Curl_llist_count(&llist); + to_remove = llist.head->next; abort_unless(to_remove, "to_remove is NULL"); element_next = to_remove->next; element_prev = to_remove->prev; - Curl_llist_remove(llist, to_remove, NULL); + Curl_llist_remove(&llist, to_remove, NULL); fail_unless(element_prev->next == element_next, "element previous->next is not being adjusted"); abort_unless(element_next, "element_next is NULL"); @@ -213,10 +206,10 @@ UNITTEST_START * 4: list->tail will be tail->previous */ - to_remove = llist->tail; + to_remove = llist.tail; element_prev = to_remove->prev; - Curl_llist_remove(llist, to_remove, NULL); - fail_unless(llist->tail == element_prev, + Curl_llist_remove(&llist, to_remove, NULL); + fail_unless(llist.tail == element_prev, "llist tail is not being adjusted when removing tail"); /** @@ -228,11 +221,11 @@ UNITTEST_START * 3: list tail will be null */ - to_remove = llist->head; - Curl_llist_remove(llist, to_remove, NULL); - fail_unless(llist->head == NULL, + to_remove = llist.head; + Curl_llist_remove(&llist, to_remove, NULL); + fail_unless(llist.head == NULL, "llist head is not NULL while the llist is empty"); - fail_unless(llist->tail == NULL, + fail_unless(llist.tail == NULL, "llist tail is not NULL while the llist is empty"); /* @testing Curl_llist_move(struct curl_llist *, @@ -255,36 +248,36 @@ UNITTEST_START * add one element to the list */ - curlErrCode = Curl_llist_insert_next(llist, llist->head, &unusedData_case1); + curlErrCode = Curl_llist_insert_next(&llist, llist.head, &unusedData_case1); /* necessary assertions */ abort_unless(curlErrCode == 1, "Curl_llist_insert_next returned an error, Can't move on with test"); - abort_unless(Curl_llist_count(llist) == 1, + abort_unless(Curl_llist_count(&llist) == 1, "Number of list elements is not as expected, Aborting"); - abort_unless(Curl_llist_count(llist_destination) == 0, + abort_unless(Curl_llist_count(&llist_destination) == 0, "Number of list elements is not as expected, Aborting"); /*actual testing code*/ - curlErrCode = Curl_llist_move(llist, llist->head, llist_destination, NULL); + curlErrCode = Curl_llist_move(&llist, llist.head, &llist_destination, NULL); abort_unless(curlErrCode == 1, "Curl_llist_move returned an error, Can't move on with test"); - fail_unless(Curl_llist_count(llist) == 0, + fail_unless(Curl_llist_count(&llist) == 0, "moving element from llist didn't decrement the size"); - fail_unless(Curl_llist_count(llist_destination) == 1, + fail_unless(Curl_llist_count(&llist_destination) == 1, "moving element to llist_destination didn't increment the size"); - fail_unless(llist->head == NULL, + fail_unless(llist.head == NULL, "llist head not set to null after moving the head"); - fail_unless(llist_destination->head != NULL, + fail_unless(llist_destination.head != NULL, "llist_destination head set to null after moving an element"); - fail_unless(llist_destination->tail != NULL, + fail_unless(llist_destination.tail != NULL, "llist_destination tail set to null after moving an element"); - fail_unless(llist_destination->tail == llist_destination->tail, + fail_unless(llist_destination.tail == llist_destination.tail, "llist_destination tail doesn't equal llist_destination head");