mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05: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
@ -56,11 +56,7 @@ static CURLcode bundle_create(struct Curl_easy *data,
|
|||||||
(*cb_ptr)->num_connections = 0;
|
(*cb_ptr)->num_connections = 0;
|
||||||
(*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
|
(*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
|
||||||
|
|
||||||
(*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
|
Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
|
||||||
if(!(*cb_ptr)->conn_list) {
|
|
||||||
Curl_safefree(*cb_ptr);
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,10 +65,8 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
|
|||||||
if(!cb_ptr)
|
if(!cb_ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(cb_ptr->conn_list) {
|
Curl_llist_destroy(&cb_ptr->conn_list, NULL);
|
||||||
Curl_llist_destroy(cb_ptr->conn_list, NULL);
|
|
||||||
cb_ptr->conn_list = NULL;
|
|
||||||
}
|
|
||||||
free(cb_ptr);
|
free(cb_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +74,7 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
|
|||||||
static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
|
static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
|
||||||
struct connectdata *conn)
|
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;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
conn->bundle = cb_ptr;
|
conn->bundle = cb_ptr;
|
||||||
@ -95,10 +89,10 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr,
|
|||||||
{
|
{
|
||||||
struct curl_llist_element *curr;
|
struct curl_llist_element *curr;
|
||||||
|
|
||||||
curr = cb_ptr->conn_list->head;
|
curr = cb_ptr->conn_list.head;
|
||||||
while(curr) {
|
while(curr) {
|
||||||
if(curr->ptr == conn) {
|
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--;
|
cb_ptr->num_connections--;
|
||||||
conn->bundle = NULL;
|
conn->bundle = NULL;
|
||||||
return 1; /* we removed a handle */
|
return 1; /* we removed a handle */
|
||||||
@ -289,7 +283,7 @@ void Curl_conncache_foreach(struct conncache *connc,
|
|||||||
bundle = he->ptr;
|
bundle = he->ptr;
|
||||||
he = Curl_hash_next_element(&iter);
|
he = Curl_hash_next_element(&iter);
|
||||||
|
|
||||||
curr = bundle->conn_list->head;
|
curr = bundle->conn_list.head;
|
||||||
while(curr) {
|
while(curr) {
|
||||||
/* Yes, we need to update curr before calling func(), because func()
|
/* Yes, we need to update curr before calling func(), because func()
|
||||||
might decide to remove the connection */
|
might decide to remove the connection */
|
||||||
@ -318,7 +312,7 @@ Curl_conncache_find_first_connection(struct conncache *connc)
|
|||||||
struct curl_llist_element *curr;
|
struct curl_llist_element *curr;
|
||||||
bundle = he->ptr;
|
bundle = he->ptr;
|
||||||
|
|
||||||
curr = bundle->conn_list->head;
|
curr = bundle->conn_list.head;
|
||||||
if(curr) {
|
if(curr) {
|
||||||
return curr->ptr;
|
return curr->ptr;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
@ -38,7 +38,7 @@ struct conncache {
|
|||||||
struct connectbundle {
|
struct connectbundle {
|
||||||
int multiuse; /* supports multi-use */
|
int multiuse; /* supports multi-use */
|
||||||
size_t num_connections; /* Number of connections in the bundle */
|
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);
|
int Curl_conncache_init(struct conncache *, int size);
|
||||||
|
15
lib/ftp.c
15
lib/ftp.c
@ -3900,7 +3900,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
wildcard->state = CURLWC_CLEAN;
|
wildcard->state = CURLWC_CLEAN;
|
||||||
return wc_statemach(conn);
|
return wc_statemach(conn);
|
||||||
}
|
}
|
||||||
if(wildcard->filelist->size == 0) {
|
if(wildcard->filelist.size == 0) {
|
||||||
/* no corresponding file */
|
/* no corresponding file */
|
||||||
wildcard->state = CURLWC_CLEAN;
|
wildcard->state = CURLWC_CLEAN;
|
||||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||||
@ -3911,7 +3911,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
case CURLWC_DOWNLOADING: {
|
case CURLWC_DOWNLOADING: {
|
||||||
/* filelist has at least one file, lets get first one */
|
/* filelist has at least one file, lets get first one */
|
||||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
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);
|
char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
|
||||||
if(!tmp_path)
|
if(!tmp_path)
|
||||||
@ -3926,7 +3926,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
||||||
if(conn->data->set.chunk_bgn) {
|
if(conn->data->set.chunk_bgn) {
|
||||||
long userresponse = 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) {
|
switch(userresponse) {
|
||||||
case CURL_CHUNK_BGN_FUNC_SKIP:
|
case CURL_CHUNK_BGN_FUNC_SKIP:
|
||||||
infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
|
infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
|
||||||
@ -3951,9 +3951,9 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* we don't need the Curl_fileinfo of first file anymore */
|
/* 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;
|
wildcard->state = CURLWC_CLEAN;
|
||||||
/* after that will be ftp_do called once again and no transfer
|
/* after that will be ftp_do called once again and no transfer
|
||||||
will be done because of CURLWC_CLEAN state */
|
will be done because of CURLWC_CLEAN state */
|
||||||
@ -3964,8 +3964,8 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
case CURLWC_SKIP: {
|
case CURLWC_SKIP: {
|
||||||
if(conn->data->set.chunk_end)
|
if(conn->data->set.chunk_end)
|
||||||
conn->data->set.chunk_end(conn->data->wildcard.customptr);
|
conn->data->set.chunk_end(conn->data->wildcard.customptr);
|
||||||
Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
|
Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||||
wildcard->state = (wildcard->filelist->size == 0) ?
|
wildcard->state = (wildcard->filelist.size == 0) ?
|
||||||
CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
||||||
return wc_statemach(conn);
|
return wc_statemach(conn);
|
||||||
}
|
}
|
||||||
@ -3981,6 +3981,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
|||||||
|
|
||||||
case CURLWC_DONE:
|
case CURLWC_DONE:
|
||||||
case CURLWC_ERROR:
|
case CURLWC_ERROR:
|
||||||
|
case CURLWC_CLEAR:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
@ -280,7 +280,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
|||||||
curl_fnmatch_callback compare;
|
curl_fnmatch_callback compare;
|
||||||
struct WildcardData *wc = &conn->data->wildcard;
|
struct WildcardData *wc = &conn->data->wildcard;
|
||||||
struct ftp_wc_tmpdata *tmpdata = wc->tmp;
|
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;
|
struct ftp_parselist_data *parser = tmpdata->parser;
|
||||||
bool add = TRUE;
|
bool add = TRUE;
|
||||||
|
|
||||||
|
30
lib/hash.c
30
lib/hash.c
@ -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
|
||||||
@ -74,21 +74,10 @@ Curl_hash_init(struct curl_hash *h,
|
|||||||
h->size = 0;
|
h->size = 0;
|
||||||
h->slots = slots;
|
h->slots = slots;
|
||||||
|
|
||||||
h->table = malloc(slots * sizeof(struct curl_llist *));
|
h->table = malloc(slots * sizeof(struct curl_llist));
|
||||||
if(h->table) {
|
if(h->table) {
|
||||||
for(i = 0; i < slots; ++i) {
|
for(i = 0; i < slots; ++i)
|
||||||
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
|
Curl_llist_init(&h->table[i], (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 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0; /* fine */
|
return 0; /* fine */
|
||||||
}
|
}
|
||||||
h->slots = 0;
|
h->slots = 0;
|
||||||
@ -119,7 +108,7 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
|
|||||||
return he;
|
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,
|
/* Insert the data in the hash. If there already was a match in the hash,
|
||||||
* that data is replaced.
|
* that data is replaced.
|
||||||
@ -241,8 +230,7 @@ Curl_hash_destroy(struct curl_hash *h)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < h->slots; ++i) {
|
for(i = 0; i < h->slots; ++i) {
|
||||||
Curl_llist_destroy(h->table[i], (void *) h);
|
Curl_llist_destroy(&h->table[i], (void *) h);
|
||||||
h->table[i] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(h->table);
|
Curl_safefree(h->table);
|
||||||
@ -274,7 +262,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for(i = 0; i < h->slots; ++i) {
|
for(i = 0; i < h->slots; ++i) {
|
||||||
list = h->table[i];
|
list = &h->table[i];
|
||||||
le = list->head; /* get first list entry */
|
le = list->head; /* get first list entry */
|
||||||
while(le) {
|
while(le) {
|
||||||
struct curl_hash_element *he = le->ptr;
|
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 we have reached the end of the list, find the next one */
|
||||||
if(!iter->current_element) {
|
if(!iter->current_element) {
|
||||||
for(i = iter->slot_index;i < h->slots;i++) {
|
for(i = iter->slot_index;i < h->slots;i++) {
|
||||||
if(h->table[i]->head) {
|
if(h->table[i].head) {
|
||||||
iter->current_element = h->table[i]->head;
|
iter->current_element = h->table[i].head;
|
||||||
iter->slot_index = i+1;
|
iter->slot_index = i+1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,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
|
||||||
@ -44,7 +44,7 @@ typedef size_t (*comp_function) (void *key1,
|
|||||||
typedef void (*curl_hash_dtor)(void *);
|
typedef void (*curl_hash_dtor)(void *);
|
||||||
|
|
||||||
struct curl_hash {
|
struct curl_hash {
|
||||||
struct curl_llist **table;
|
struct curl_llist *table;
|
||||||
|
|
||||||
/* Hash function to be used for this hash table */
|
/* Hash function to be used for this hash table */
|
||||||
hash_function hash_func;
|
hash_function hash_func;
|
||||||
|
22
lib/llist.c
22
lib/llist.c
@ -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
|
||||||
@ -33,8 +33,8 @@
|
|||||||
/*
|
/*
|
||||||
* @unittest: 1300
|
* @unittest: 1300
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
||||||
{
|
{
|
||||||
l->size = 0;
|
l->size = 0;
|
||||||
l->dtor = dtor;
|
l->dtor = dtor;
|
||||||
@ -42,20 +42,6 @@ llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
|||||||
l->tail = NULL;
|
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()
|
* Curl_llist_insert_next()
|
||||||
*
|
*
|
||||||
@ -149,8 +135,6 @@ Curl_llist_destroy(struct curl_llist *list, void *user)
|
|||||||
if(list) {
|
if(list) {
|
||||||
while(list->size > 0)
|
while(list->size > 0)
|
||||||
Curl_llist_remove(list, list->tail, user);
|
Curl_llist_remove(list, list->tail, user);
|
||||||
|
|
||||||
free(list);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2010, 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
|
||||||
@ -43,7 +43,7 @@ struct curl_llist {
|
|||||||
size_t size;
|
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 *,
|
int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
|
||||||
const void *);
|
const void *);
|
||||||
int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
|
int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
|
||||||
|
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,
|
static CURLMcode multi_addmsg(struct Curl_multi *multi,
|
||||||
struct Curl_message *msg)
|
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_OUT_OF_MEMORY;
|
||||||
|
|
||||||
return CURLM_OK;
|
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))
|
if(Curl_conncache_init(&multi->conn_cache, chashsize))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
multi->msglist = Curl_llist_alloc(multi_freeamsg);
|
Curl_llist_init(&multi->msglist, multi_freeamsg);
|
||||||
if(!multi->msglist)
|
Curl_llist_init(&multi->pending, multi_freeamsg);
|
||||||
goto error;
|
|
||||||
|
|
||||||
multi->pending = Curl_llist_alloc(multi_freeamsg);
|
|
||||||
if(!multi->pending)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* allocate a new easy handle to use when closing cached connections */
|
/* allocate a new easy handle to use when closing cached connections */
|
||||||
multi->closure_handle = curl_easy_init();
|
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_conncache_destroy(&multi->conn_cache);
|
||||||
Curl_close(multi->closure_handle);
|
Curl_close(multi->closure_handle);
|
||||||
multi->closure_handle = NULL;
|
multi->closure_handle = NULL;
|
||||||
Curl_llist_destroy(multi->msglist, NULL);
|
Curl_llist_destroy(&multi->msglist, NULL);
|
||||||
Curl_llist_destroy(multi->pending, NULL);
|
Curl_llist_destroy(&multi->pending, NULL);
|
||||||
|
|
||||||
free(multi);
|
free(multi);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -361,8 +356,6 @@ struct Curl_multi *curl_multi_init(void)
|
|||||||
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct curl_llist *timeoutlist;
|
|
||||||
|
|
||||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||||
if(!GOOD_MULTI_HANDLE(multi))
|
if(!GOOD_MULTI_HANDLE(multi))
|
||||||
return CURLM_BAD_HANDLE;
|
return CURLM_BAD_HANDLE;
|
||||||
@ -376,10 +369,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||||||
if(data->multi)
|
if(data->multi)
|
||||||
return CURLM_ADDED_ALREADY;
|
return CURLM_ADDED_ALREADY;
|
||||||
|
|
||||||
/* Allocate and initialize timeout list for easy handle */
|
/* Initialize timeout list for this handle */
|
||||||
timeoutlist = Curl_llist_alloc(multi_freetimeout);
|
Curl_llist_init(&data->state.timeoutlist, multi_freetimeout);
|
||||||
if(!timeoutlist)
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No failure allowed in this function beyond this point. And no
|
* 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.
|
* function no matter what.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Make easy handle use timeout list initialized above */
|
|
||||||
data->state.timeoutlist = timeoutlist;
|
|
||||||
timeoutlist = NULL;
|
|
||||||
|
|
||||||
/* set the easy handle */
|
/* set the easy handle */
|
||||||
multistate(data, CURLM_STATE_INIT);
|
multistate(data, CURLM_STATE_INIT);
|
||||||
|
|
||||||
@ -580,7 +567,7 @@ static CURLcode multi_done(struct connectdata **connp,
|
|||||||
result = CURLE_ABORTED_BY_CALLBACK;
|
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 &&
|
!data->set.reuse_forbid &&
|
||||||
!conn->bits.close) {
|
!conn->bits.close) {
|
||||||
/* Stop if pipeline is not empty and we do not have to 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*
|
/* 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 */
|
multi_done() as that may actually call Curl_expire that uses this */
|
||||||
if(data->state.timeoutlist) {
|
Curl_llist_destroy(&data->state.timeoutlist, NULL);
|
||||||
Curl_llist_destroy(data->state.timeoutlist, NULL);
|
|
||||||
data->state.timeoutlist = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* as this was using a shared connection cache we clear the pointer to that
|
/* as this was using a shared connection cache we clear the pointer to that
|
||||||
since we're not part of that multi handle anymore */
|
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
|
/* make sure there's no pending message in the queue sent from this easy
|
||||||
handle */
|
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;
|
struct Curl_message *msg = e->ptr;
|
||||||
|
|
||||||
if(msg->extmsg.easy_handle == easy) {
|
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 */
|
/* there can only be one from this specific handle */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1448,7 +1432,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
multistate(data, CURLM_STATE_CONNECT_PEND);
|
multistate(data, CURLM_STATE_CONNECT_PEND);
|
||||||
|
|
||||||
/* add this handle to the list of connect-pending handles */
|
/* 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;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
else
|
else
|
||||||
result = CURLE_OK;
|
result = CURLE_OK;
|
||||||
@ -1954,11 +1938,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
Curl_posttransfer(data);
|
Curl_posttransfer(data);
|
||||||
|
|
||||||
/* we're no longer receiving */
|
/* 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 */
|
/* 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);
|
||||||
|
|
||||||
/* 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);
|
||||||
@ -2023,7 +2007,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
CURLcode res;
|
CURLcode res;
|
||||||
|
|
||||||
/* Remove ourselves from the receive pipeline, if we are there. */
|
/* 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 */
|
/* Check if we can move pending requests to send pipe */
|
||||||
Curl_multi_process_pending_handles(multi);
|
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 */
|
/* if this has a connection, unsubscribe from the pipelines */
|
||||||
Curl_pipeline_leave_write(data->easy_conn);
|
Curl_pipeline_leave_write(data->easy_conn);
|
||||||
Curl_pipeline_leave_read(data->easy_conn);
|
Curl_pipeline_leave_read(data->easy_conn);
|
||||||
Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
|
Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
|
||||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||||
|
|
||||||
if(stream_error) {
|
if(stream_error) {
|
||||||
/* Don't attempt to send data over a connection that timed out */
|
/* 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_hash_destroy(&multi->sockhash);
|
||||||
Curl_conncache_destroy(&multi->conn_cache);
|
Curl_conncache_destroy(&multi->conn_cache);
|
||||||
Curl_llist_destroy(multi->msglist, NULL);
|
Curl_llist_destroy(&multi->msglist, NULL);
|
||||||
Curl_llist_destroy(multi->pending, NULL);
|
Curl_llist_destroy(&multi->pending, NULL);
|
||||||
|
|
||||||
/* remove all easy handles */
|
/* remove all easy handles */
|
||||||
data = multi->easyp;
|
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 */
|
*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 */
|
/* there is one or more messages in the list */
|
||||||
struct curl_llist_element *e;
|
struct curl_llist_element *e;
|
||||||
|
|
||||||
/* extract the head of the list to return */
|
/* extract the head of the list to return */
|
||||||
e = multi->msglist->head;
|
e = multi->msglist.head;
|
||||||
|
|
||||||
msg = e->ptr;
|
msg = e->ptr;
|
||||||
|
|
||||||
/* remove the extracted entry */
|
/* 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;
|
return &msg->extmsg;
|
||||||
}
|
}
|
||||||
@ -2418,7 +2402,7 @@ static void singlesocket(struct Curl_multi *multi,
|
|||||||
removed. */
|
removed. */
|
||||||
struct connectdata *easy_conn = data->easy_conn;
|
struct connectdata *easy_conn = data->easy_conn;
|
||||||
if(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 */
|
/* the handle should not be removed from the pipe yet */
|
||||||
remove_sock_from_hash = FALSE;
|
remove_sock_from_hash = FALSE;
|
||||||
|
|
||||||
@ -2427,12 +2411,12 @@ static void singlesocket(struct Curl_multi *multi,
|
|||||||
isn't already) */
|
isn't already) */
|
||||||
if(entry->easy == data) {
|
if(entry->easy == data) {
|
||||||
if(Curl_recvpipe_head(data, easy_conn))
|
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
|
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 */
|
/* the handle should not be removed from the pipe yet */
|
||||||
remove_sock_from_hash = FALSE;
|
remove_sock_from_hash = FALSE;
|
||||||
|
|
||||||
@ -2441,9 +2425,9 @@ static void singlesocket(struct Curl_multi *multi,
|
|||||||
isn't already) */
|
isn't already) */
|
||||||
if(entry->easy == data) {
|
if(entry->easy == data) {
|
||||||
if(Curl_sendpipe_head(data, easy_conn))
|
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
|
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,
|
/* 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 Curl_easy *d)
|
||||||
{
|
{
|
||||||
struct timeval *tv = &d->state.expiretime;
|
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;
|
struct curl_llist_element *e;
|
||||||
|
|
||||||
/* move over the timeout list for this specific handle and remove all
|
/* 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. */
|
head. If we should read from the socket, take the recv_pipe head. */
|
||||||
if(data->easy_conn) {
|
if(data->easy_conn) {
|
||||||
if((ev_bitmask & CURL_POLL_OUT) &&
|
if((ev_bitmask & CURL_POLL_OUT) &&
|
||||||
data->easy_conn->send_pipe &&
|
data->easy_conn->send_pipe.head)
|
||||||
data->easy_conn->send_pipe->head)
|
data = data->easy_conn->send_pipe.head->ptr;
|
||||||
data = data->easy_conn->send_pipe->head->ptr;
|
|
||||||
else if((ev_bitmask & CURL_POLL_IN) &&
|
else if((ev_bitmask & CURL_POLL_IN) &&
|
||||||
data->easy_conn->recv_pipe &&
|
data->easy_conn->recv_pipe.head)
|
||||||
data->easy_conn->recv_pipe->head)
|
data = data->easy_conn->recv_pipe.head->ptr;
|
||||||
data = data->easy_conn->recv_pipe->head->ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->easy_conn &&
|
if(data->easy_conn &&
|
||||||
@ -2967,13 +2949,13 @@ void Curl_expire(struct Curl_easy *data, time_t milli)
|
|||||||
if(diff > 0) {
|
if(diff > 0) {
|
||||||
/* the new expire time was later so just add it to the queue
|
/* the new expire time was later so just add it to the queue
|
||||||
and get out */
|
and get out */
|
||||||
multi_addtimeout(data->state.timeoutlist, &set);
|
multi_addtimeout(&data->state.timeoutlist, &set);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the new time is newer than the presently set one, so add the current
|
/* the new time is newer than the presently set one, so add the current
|
||||||
to the queue and update the head */
|
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
|
/* Since this is an updated time, we must remove the previous entry from
|
||||||
the splay tree first and then re-add the new value */
|
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) {
|
if(nowp->tv_sec || nowp->tv_usec) {
|
||||||
/* Since this is an cleared time, we must remove the previous entry from
|
/* Since this is an cleared time, we must remove the previous entry from
|
||||||
the splay tree */
|
the splay tree */
|
||||||
struct curl_llist *list = data->state.timeoutlist;
|
struct curl_llist *list = &data->state.timeoutlist;
|
||||||
|
|
||||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||||
&data->state.timenode,
|
&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)
|
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)
|
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)
|
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) {
|
while(e) {
|
||||||
struct Curl_easy *data = e->ptr;
|
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);
|
multistate(data, CURLM_STATE_CONNECT);
|
||||||
|
|
||||||
/* Remove this node from the list */
|
/* 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. */
|
/* Make sure that the handle will be processed soonish. */
|
||||||
Curl_expire_latest(data, 0);
|
Curl_expire_latest(data, 0);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2015, 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
|
||||||
@ -80,9 +80,9 @@ struct Curl_multi {
|
|||||||
int num_alive; /* amount of easy handles that are added but have not yet
|
int num_alive; /* amount of easy handles that are added but have not yet
|
||||||
reached COMPLETE state */
|
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
|
struct curl_llist pending; /* Curl_easys that are in the
|
||||||
CURLM_STATE_CONNECT_PEND state */
|
CURLM_STATE_CONNECT_PEND state */
|
||||||
|
|
||||||
/* callback function and user data pointer for the *socket() API */
|
/* callback function and user data pointer for the *socket() API */
|
||||||
@ -138,10 +138,10 @@ struct Curl_multi {
|
|||||||
bigger than this is not
|
bigger than this is not
|
||||||
considered for pipelining */
|
considered for pipelining */
|
||||||
|
|
||||||
struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted
|
struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted
|
||||||
from pipelining */
|
from pipelining */
|
||||||
|
|
||||||
struct curl_llist *pipelining_server_bl; /* List of server types that are
|
struct curl_llist pipelining_server_bl; /* List of server types that are
|
||||||
blacklisted from pipelining */
|
blacklisted from pipelining */
|
||||||
|
|
||||||
/* timer callback and user data pointer for the *socket() API */
|
/* timer callback and user data pointer for the *socket() API */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
|
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||||
* Copyright (C) 2013-2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2013 - 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
|
||||||
@ -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 */
|
curl_off_t recv_size = -2; /* Make it easy to spot in the log */
|
||||||
|
|
||||||
/* Find the head of the recv pipe, if any */
|
/* Find the head of the recv pipe, if any */
|
||||||
if(conn->recv_pipe && conn->recv_pipe->head) {
|
if(conn->recv_pipe.head) {
|
||||||
struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr;
|
struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr;
|
||||||
|
|
||||||
recv_size = recv_handle->req.size;
|
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,
|
CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
|
||||||
struct connectdata *conn)
|
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;
|
struct curl_llist *pipeline;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
pipeline = conn->send_pipe;
|
pipeline = &conn->send_pipe;
|
||||||
|
|
||||||
result = addHandleToPipeline(handle, pipeline);
|
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 */
|
/* 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);
|
Curl_expire(conn->send_pipe.head->ptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* enable for pipeline debugging */
|
#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;
|
struct curl_llist_element *curr;
|
||||||
|
|
||||||
curr = conn->send_pipe->head;
|
curr = conn->send_pipe.head;
|
||||||
while(curr) {
|
while(curr) {
|
||||||
if(curr->ptr == handle) {
|
if(curr->ptr == handle) {
|
||||||
Curl_llist_move(conn->send_pipe, curr,
|
Curl_llist_move(&conn->send_pipe, curr,
|
||||||
conn->recv_pipe, conn->recv_pipe->tail);
|
&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,
|
/* 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 */
|
set its timeout value to 1ms to make it trigger instantly */
|
||||||
Curl_pipeline_leave_write(conn); /* not used now */
|
Curl_pipeline_leave_write(conn); /* not used now */
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
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);
|
Curl_expire(conn->send_pipe.head->ptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The receiver's list is not really interesting here since either this
|
/* 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,
|
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||||
struct curl_llist **list_ptr)
|
struct curl_llist *list)
|
||||||
{
|
{
|
||||||
struct curl_llist *old_list = *list_ptr;
|
/* Free the old list */
|
||||||
struct curl_llist *new_list = NULL;
|
if(list->size)
|
||||||
|
Curl_llist_destroy(list, NULL);
|
||||||
|
|
||||||
if(sites) {
|
if(sites) {
|
||||||
new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
|
Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor);
|
||||||
if(!new_list)
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* Parse the URLs and populate the list */
|
/* Parse the URLs and populate the list */
|
||||||
while(*sites) {
|
while(*sites) {
|
||||||
@ -209,14 +208,14 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
|||||||
|
|
||||||
hostname = strdup(*sites);
|
hostname = strdup(*sites);
|
||||||
if(!hostname) {
|
if(!hostname) {
|
||||||
Curl_llist_destroy(new_list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = malloc(sizeof(struct site_blacklist_entry));
|
entry = malloc(sizeof(struct site_blacklist_entry));
|
||||||
if(!entry) {
|
if(!entry) {
|
||||||
free(hostname);
|
free(hostname);
|
||||||
Curl_llist_destroy(new_list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,9 +232,9 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
|||||||
|
|
||||||
entry->hostname = hostname;
|
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);
|
site_blacklist_llist_dtor(NULL, entry);
|
||||||
Curl_llist_destroy(new_list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
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;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,15 +275,14 @@ bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||||
struct curl_llist **list_ptr)
|
struct curl_llist *list)
|
||||||
{
|
{
|
||||||
struct curl_llist *old_list = *list_ptr;
|
/* Free the old list */
|
||||||
struct curl_llist *new_list = NULL;
|
if(list->size)
|
||||||
|
Curl_llist_destroy(list, NULL);
|
||||||
|
|
||||||
if(servers) {
|
if(servers) {
|
||||||
new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
|
Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor);
|
||||||
if(!new_list)
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* Parse the URLs and populate the list */
|
/* Parse the URLs and populate the list */
|
||||||
while(*servers) {
|
while(*servers) {
|
||||||
@ -300,12 +290,12 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
|||||||
|
|
||||||
server_name = strdup(*servers);
|
server_name = strdup(*servers);
|
||||||
if(!server_name) {
|
if(!server_name) {
|
||||||
Curl_llist_destroy(new_list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) {
|
if(!Curl_llist_insert_next(list, list->tail, server_name)) {
|
||||||
Curl_llist_destroy(new_list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
Curl_safefree(server_name);
|
Curl_safefree(server_name);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
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;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
@ -340,14 +323,14 @@ static bool pipe_head(struct Curl_easy *data,
|
|||||||
bool Curl_recvpipe_head(struct Curl_easy *data,
|
bool Curl_recvpipe_head(struct Curl_easy *data,
|
||||||
struct connectdata *conn)
|
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 */
|
/* returns TRUE if the given handle is head of the send pipe */
|
||||||
bool Curl_sendpipe_head(struct Curl_easy *data,
|
bool Curl_sendpipe_head(struct Curl_easy *data,
|
||||||
struct connectdata *conn)
|
struct connectdata *conn)
|
||||||
{
|
{
|
||||||
return pipe_head(data, conn->send_pipe);
|
return pipe_head(data, &conn->send_pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
* Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
* Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* 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);
|
struct connectdata *conn);
|
||||||
|
|
||||||
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
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,
|
bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||||
char *server_name);
|
char *server_name);
|
||||||
|
|
||||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
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,
|
bool Curl_pipeline_checkget_write(struct Curl_easy *data,
|
||||||
struct connectdata *conn);
|
struct connectdata *conn);
|
||||||
|
@ -1356,13 +1356,12 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
|||||||
|
|
||||||
if(data->set.wildcardmatch) {
|
if(data->set.wildcardmatch) {
|
||||||
struct WildcardData *wc = &data->wildcard;
|
struct WildcardData *wc = &data->wildcard;
|
||||||
if(!wc->filelist) {
|
if(wc->state < CURLWC_INIT) {
|
||||||
result = Curl_wildcard_init(wc); /* init wildcard structures */
|
result = Curl_wildcard_init(wc); /* init wildcard structures */
|
||||||
if(result)
|
if(result)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
67
lib/url.c
67
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
|
/* 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
|
/normally/ done by curl_multi_remove_handle() but this is "just in
|
||||||
case" */
|
case" */
|
||||||
if(data->state.timeoutlist) {
|
Curl_llist_destroy(&data->state.timeoutlist, NULL);
|
||||||
Curl_llist_destroy(data->state.timeoutlist, NULL);
|
|
||||||
data->state.timeoutlist = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->magic = 0; /* force a clear AFTER the possibly enforced removal from
|
data->magic = 0; /* force a clear AFTER the possibly enforced removal from
|
||||||
the multi handle, since that function uses the magic
|
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->progress.flags |= PGRS_HIDE;
|
||||||
data->state.current_speed = -1; /* init to negative == impossible */
|
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.fnmatch = ZERO_NULL;
|
||||||
data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
|
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);
|
conn_reset_all_postponed_data(conn);
|
||||||
|
|
||||||
Curl_llist_destroy(conn->send_pipe, NULL);
|
Curl_llist_destroy(&conn->send_pipe, NULL);
|
||||||
Curl_llist_destroy(conn->recv_pipe, NULL);
|
Curl_llist_destroy(&conn->recv_pipe, NULL);
|
||||||
|
|
||||||
conn->send_pipe = NULL;
|
|
||||||
conn->recv_pipe = NULL;
|
|
||||||
|
|
||||||
Curl_safefree(conn->localdev);
|
Curl_safefree(conn->localdev);
|
||||||
Curl_free_primary_ssl_config(&conn->ssl_config);
|
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
|
* are other users of it
|
||||||
*/
|
*/
|
||||||
if(!conn->bits.close &&
|
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",
|
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;
|
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 */
|
/* Indicate to all handles on the pipe that we're dead */
|
||||||
if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
|
if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
|
||||||
signalPipeClose(conn->send_pipe, TRUE);
|
signalPipeClose(&conn->send_pipe, TRUE);
|
||||||
signalPipeClose(conn->recv_pipe, TRUE);
|
signalPipeClose(&conn->recv_pipe, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
conn_free(conn);
|
conn_free(conn);
|
||||||
@ -3186,9 +3177,9 @@ void Curl_getoff_all_pipelines(struct Curl_easy *data,
|
|||||||
bool send_head = (conn->writechannel_inuse &&
|
bool send_head = (conn->writechannel_inuse &&
|
||||||
Curl_sendpipe_head(data, conn));
|
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);
|
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);
|
Curl_pipeline_leave_write(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3249,7 +3240,7 @@ Curl_oldest_idle_connection(struct Curl_easy *data)
|
|||||||
|
|
||||||
bundle = he->ptr;
|
bundle = he->ptr;
|
||||||
|
|
||||||
curr = bundle->conn_list->head;
|
curr = bundle->conn_list.head;
|
||||||
while(curr) {
|
while(curr) {
|
||||||
conn = curr->ptr;
|
conn = curr->ptr;
|
||||||
|
|
||||||
@ -3306,7 +3297,7 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
|
|||||||
|
|
||||||
now = Curl_tvnow();
|
now = Curl_tvnow();
|
||||||
|
|
||||||
curr = bundle->conn_list->head;
|
curr = bundle->conn_list.head;
|
||||||
while(curr) {
|
while(curr) {
|
||||||
conn = curr->ptr;
|
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,
|
static bool disconnect_if_dead(struct connectdata *conn,
|
||||||
struct Curl_easy *data)
|
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) {
|
if(!pipeLen && !conn->inuse) {
|
||||||
/* The check for a dead socket makes sense only if there are no
|
/* The check for a dead socket makes sense only if there are no
|
||||||
handles in pipeline and the connection isn't already marked in
|
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) {
|
while(curr) {
|
||||||
bool match = FALSE;
|
bool match = FALSE;
|
||||||
size_t pipeLen;
|
size_t pipeLen;
|
||||||
@ -3496,7 +3487,7 @@ ConnectionExists(struct Curl_easy *data,
|
|||||||
if(disconnect_if_dead(check, data))
|
if(disconnect_if_dead(check, data))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pipeLen = check->send_pipe->size + check->recv_pipe->size;
|
pipeLen = check->send_pipe.size + check->recv_pipe.size;
|
||||||
|
|
||||||
if(canPipeline) {
|
if(canPipeline) {
|
||||||
if(check->bits.protoconnstart && check->bits.close)
|
if(check->bits.protoconnstart && check->bits.close)
|
||||||
@ -3504,8 +3495,8 @@ ConnectionExists(struct Curl_easy *data,
|
|||||||
|
|
||||||
if(!check->bits.multiplex) {
|
if(!check->bits.multiplex) {
|
||||||
/* If not multiplexing, make sure the pipe has only GET requests */
|
/* If not multiplexing, make sure the pipe has only GET requests */
|
||||||
struct Curl_easy* sh = gethandleathead(check->send_pipe);
|
struct Curl_easy* sh = gethandleathead(&check->send_pipe);
|
||||||
struct Curl_easy* rh = gethandleathead(check->recv_pipe);
|
struct Curl_easy* rh = gethandleathead(&check->recv_pipe);
|
||||||
if(sh) {
|
if(sh) {
|
||||||
if(!IsPipeliningPossible(sh, check))
|
if(!IsPipeliningPossible(sh, check))
|
||||||
continue;
|
continue;
|
||||||
@ -3543,7 +3534,7 @@ ConnectionExists(struct Curl_easy *data,
|
|||||||
infof(data, "Connection #%ld isn't open enough, can't reuse\n",
|
infof(data, "Connection #%ld isn't open enough, can't reuse\n",
|
||||||
check->connection_id);
|
check->connection_id);
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
if(check->recv_pipe->size > 0) {
|
if(check->recv_pipe.size > 0) {
|
||||||
infof(data,
|
infof(data,
|
||||||
"BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
|
"BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
|
||||||
check->connection_id);
|
check->connection_id);
|
||||||
@ -4217,10 +4208,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the pipeline lists */
|
/* Initialize the pipeline lists */
|
||||||
conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
|
Curl_llist_init(&conn->send_pipe, (curl_llist_dtor) llist_dtor);
|
||||||
conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
|
Curl_llist_init(&conn->recv_pipe, (curl_llist_dtor) llist_dtor);
|
||||||
if(!conn->send_pipe || !conn->recv_pipe)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
#ifdef HAVE_GSSAPI
|
||||||
conn->data_prot = PROT_CLEAR;
|
conn->data_prot = PROT_CLEAR;
|
||||||
@ -4243,11 +4232,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
|
|||||||
return conn;
|
return conn;
|
||||||
error:
|
error:
|
||||||
|
|
||||||
Curl_llist_destroy(conn->send_pipe, NULL);
|
Curl_llist_destroy(&conn->send_pipe, NULL);
|
||||||
Curl_llist_destroy(conn->recv_pipe, NULL);
|
Curl_llist_destroy(&conn->recv_pipe, NULL);
|
||||||
|
|
||||||
conn->send_pipe = NULL;
|
|
||||||
conn->recv_pipe = NULL;
|
|
||||||
|
|
||||||
free(conn->master_buffer);
|
free(conn->master_buffer);
|
||||||
free(conn->localdev);
|
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->socks_proxy.passwd);
|
||||||
Curl_safefree(old_conn->localdev);
|
Curl_safefree(old_conn->localdev);
|
||||||
|
|
||||||
Curl_llist_destroy(old_conn->send_pipe, NULL);
|
Curl_llist_destroy(&old_conn->send_pipe, NULL);
|
||||||
Curl_llist_destroy(old_conn->recv_pipe, NULL);
|
Curl_llist_destroy(&old_conn->recv_pipe, NULL);
|
||||||
|
|
||||||
old_conn->send_pipe = NULL;
|
|
||||||
old_conn->recv_pipe = NULL;
|
|
||||||
|
|
||||||
Curl_safefree(old_conn->master_buffer);
|
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
|
/* If we found a reusable connection, we may still want to
|
||||||
open a new connection if we are pipelining. */
|
open a new connection if we are pipelining. */
|
||||||
if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
|
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) {
|
if(pipelen > 0) {
|
||||||
infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
|
infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
|
||||||
conn_temp->connection_id, pipelen);
|
conn_temp->connection_id, pipelen);
|
||||||
@ -6913,7 +6896,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
|
|||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
/* no error */
|
/* 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 */
|
/* pipelining */
|
||||||
*protocol_done = TRUE;
|
*protocol_done = TRUE;
|
||||||
else if(!*asyncp) {
|
else if(!*asyncp) {
|
||||||
|
@ -1058,10 +1058,10 @@ struct connectdata {
|
|||||||
handle */
|
handle */
|
||||||
bool writechannel_inuse; /* whether the write channel is in use by an easy
|
bool writechannel_inuse; /* whether the write channel is in use by an easy
|
||||||
handle */
|
handle */
|
||||||
struct curl_llist *send_pipe; /* List of handles waiting to
|
struct curl_llist send_pipe; /* List of handles waiting to send on this
|
||||||
send on this pipeline */
|
pipeline */
|
||||||
struct curl_llist *recv_pipe; /* List of handles waiting to read
|
struct curl_llist recv_pipe; /* List of handles waiting to read their
|
||||||
their responses on this pipeline */
|
responses on this pipeline */
|
||||||
char *master_buffer; /* The master buffer allocated on-demand;
|
char *master_buffer; /* The master buffer allocated on-demand;
|
||||||
used for pipelining. */
|
used for pipelining. */
|
||||||
size_t read_pos; /* Current read position in the master buffer */
|
size_t read_pos; /* Current read position in the master buffer */
|
||||||
@ -1374,7 +1374,7 @@ struct UrlState {
|
|||||||
#endif /* USE_OPENSSL */
|
#endif /* USE_OPENSSL */
|
||||||
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 */
|
||||||
|
|
||||||
/* 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;
|
||||||
|
@ -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
|
||||||
@ -32,13 +32,9 @@
|
|||||||
|
|
||||||
CURLcode Curl_wildcard_init(struct WildcardData *wc)
|
CURLcode Curl_wildcard_init(struct WildcardData *wc)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(wc->filelist == NULL);
|
Curl_llist_init(&wc->filelist, Curl_fileinfo_dtor);
|
||||||
/* now allocate only wc->filelist, everything else
|
wc->state = CURLWC_INIT;
|
||||||
will be allocated if it is needed. */
|
|
||||||
wc->filelist = Curl_llist_alloc(Curl_fileinfo_dtor);
|
|
||||||
if(!wc->filelist) {;
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,10 +50,8 @@ void Curl_wildcard_dtor(struct WildcardData *wc)
|
|||||||
}
|
}
|
||||||
DEBUGASSERT(wc->tmp == NULL);
|
DEBUGASSERT(wc->tmp == NULL);
|
||||||
|
|
||||||
if(wc->filelist) {
|
Curl_llist_destroy(&wc->filelist, NULL);
|
||||||
Curl_llist_destroy(wc->filelist, NULL);
|
|
||||||
wc->filelist = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(wc->path);
|
free(wc->path);
|
||||||
wc->path = NULL;
|
wc->path = NULL;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2010 - 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
|
||||||
@ -24,9 +24,12 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "llist.h"
|
||||||
|
|
||||||
/* list of wildcard process states */
|
/* list of wildcard process states */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CURLWC_INIT = 0,
|
CURLWC_CLEAR = 0,
|
||||||
|
CURLWC_INIT = 1,
|
||||||
CURLWC_MATCHING, /* library is trying to get list of addresses for
|
CURLWC_MATCHING, /* library is trying to get list of addresses for
|
||||||
downloading */
|
downloading */
|
||||||
CURLWC_DOWNLOADING,
|
CURLWC_DOWNLOADING,
|
||||||
@ -44,7 +47,7 @@ struct WildcardData {
|
|||||||
curl_wildcard_states state;
|
curl_wildcard_states state;
|
||||||
char *path; /* path to the directory, where we trying wildcard-match */
|
char *path; /* path to the directory, where we trying wildcard-match */
|
||||||
char *pattern; /* wildcard pattern */
|
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 */
|
void *tmp; /* pointer to protocol specific temporary data */
|
||||||
curl_wildcard_tmp_dtor tmp_dtor;
|
curl_wildcard_tmp_dtor tmp_dtor;
|
||||||
void *customptr; /* for CURLOPT_CHUNK_DATA pointer */
|
void *customptr; /* for CURLOPT_CHUNK_DATA pointer */
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
|
|
||||||
#include "llist.h"
|
#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)
|
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)
|
static CURLcode unit_setup(void)
|
||||||
{
|
{
|
||||||
llist = Curl_llist_alloc(test_curl_llist_dtor);
|
Curl_llist_init(&llist, test_curl_llist_dtor);
|
||||||
if(!llist)
|
Curl_llist_init(&llist_destination, test_curl_llist_dtor);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unit_stop(void)
|
static void unit_stop(void)
|
||||||
{
|
{
|
||||||
Curl_llist_destroy(llist, NULL);
|
Curl_llist_destroy(&llist, NULL);
|
||||||
Curl_llist_destroy(llist_destination, NULL);
|
Curl_llist_destroy(&llist_destination, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNITTEST_START
|
UNITTEST_START
|
||||||
@ -62,7 +55,7 @@ UNITTEST_START
|
|||||||
struct curl_llist_element *element_next;
|
struct curl_llist_element *element_next;
|
||||||
struct curl_llist_element *element_prev;
|
struct curl_llist_element *element_prev;
|
||||||
struct curl_llist_element *to_remove;
|
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;
|
int curlErrCode = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,10 +69,10 @@ UNITTEST_START
|
|||||||
* 4: list dtor will be NULL
|
* 4: list dtor will be NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fail_unless(llist->size == 0, "list initial size should be zero");
|
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.head == NULL, "list head should initiate to NULL");
|
||||||
fail_unless(llist->tail == NULL, "list tail should intiate to NULL");
|
fail_unless(llist.tail == NULL, "list tail should intiate to NULL");
|
||||||
fail_unless(llist->dtor == test_curl_llist_dtor,
|
fail_unless(llist.dtor == test_curl_llist_dtor,
|
||||||
"list dtor shold initiate to 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
|
* 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) {
|
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");
|
"List size should be 1 after adding a new element");
|
||||||
/*test that the list head data holds my unusedData */
|
/*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");
|
"List size should be 1 after adding a new element");
|
||||||
/*same goes for the list tail */
|
/*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");
|
"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
|
* 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);
|
&unusedData_case3);
|
||||||
if(curlErrCode == 1) {
|
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");
|
"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");
|
"the list tail is not getting set correctly");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -134,13 +127,13 @@ UNITTEST_START
|
|||||||
* 2: the list tail should different from newly created element
|
* 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);
|
&unusedData_case2);
|
||||||
if(curlErrCode == 1) {
|
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");
|
"the node next to head is not getting set correctly");
|
||||||
/* better safe than sorry, check that the tail isn't corrupted */
|
/* 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");
|
"the list tail is not getting set correctly");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -165,19 +158,19 @@ UNITTEST_START
|
|||||||
* 3: "new" head's previous will be NULL
|
* 3: "new" head's previous will be NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
head=llist->head;
|
head=llist.head;
|
||||||
abort_unless(head, "llist->head is NULL");
|
abort_unless(head, "llist.head is NULL");
|
||||||
element_next = head->next;
|
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");
|
"llist size not decremented as expected");
|
||||||
fail_unless(llist->head == element_next,
|
fail_unless(llist.head == element_next,
|
||||||
"llist new head not modified properly");
|
"llist new head not modified properly");
|
||||||
abort_unless(llist->head, "llist->head is NULL");
|
abort_unless(llist.head, "llist.head is NULL");
|
||||||
fail_unless(llist->head->prev == NULL,
|
fail_unless(llist.head->prev == NULL,
|
||||||
"new head previous not set to null");
|
"new head previous not set to null");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,13 +183,13 @@ UNITTEST_START
|
|||||||
* 2: element->previous->next will be element->next
|
* 2: element->previous->next will be element->next
|
||||||
* 3: element->next->previous will be element->previous
|
* 3: element->next->previous will be element->previous
|
||||||
*/
|
*/
|
||||||
Curl_llist_insert_next(llist, llist->head, &unusedData_case3);
|
Curl_llist_insert_next(&llist, llist.head, &unusedData_case3);
|
||||||
llist_size = Curl_llist_count(llist);
|
llist_size = Curl_llist_count(&llist);
|
||||||
to_remove = llist->head->next;
|
to_remove = llist.head->next;
|
||||||
abort_unless(to_remove, "to_remove is NULL");
|
abort_unless(to_remove, "to_remove is NULL");
|
||||||
element_next = to_remove->next;
|
element_next = to_remove->next;
|
||||||
element_prev = to_remove->prev;
|
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,
|
fail_unless(element_prev->next == element_next,
|
||||||
"element previous->next is not being adjusted");
|
"element previous->next is not being adjusted");
|
||||||
abort_unless(element_next, "element_next is NULL");
|
abort_unless(element_next, "element_next is NULL");
|
||||||
@ -213,10 +206,10 @@ UNITTEST_START
|
|||||||
* 4: list->tail will be tail->previous
|
* 4: list->tail will be tail->previous
|
||||||
*/
|
*/
|
||||||
|
|
||||||
to_remove = llist->tail;
|
to_remove = llist.tail;
|
||||||
element_prev = to_remove->prev;
|
element_prev = to_remove->prev;
|
||||||
Curl_llist_remove(llist, to_remove, NULL);
|
Curl_llist_remove(&llist, to_remove, NULL);
|
||||||
fail_unless(llist->tail == element_prev,
|
fail_unless(llist.tail == element_prev,
|
||||||
"llist tail is not being adjusted when removing tail");
|
"llist tail is not being adjusted when removing tail");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,11 +221,11 @@ UNITTEST_START
|
|||||||
* 3: list tail will be null
|
* 3: list tail will be null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
to_remove = llist->head;
|
to_remove = llist.head;
|
||||||
Curl_llist_remove(llist, to_remove, NULL);
|
Curl_llist_remove(&llist, to_remove, NULL);
|
||||||
fail_unless(llist->head == NULL,
|
fail_unless(llist.head == NULL,
|
||||||
"llist head is not NULL while the llist is empty");
|
"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");
|
"llist tail is not NULL while the llist is empty");
|
||||||
|
|
||||||
/* @testing Curl_llist_move(struct curl_llist *,
|
/* @testing Curl_llist_move(struct curl_llist *,
|
||||||
@ -255,36 +248,36 @@ UNITTEST_START
|
|||||||
* add one element to the list
|
* 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 */
|
/* necessary assertions */
|
||||||
|
|
||||||
abort_unless(curlErrCode == 1,
|
abort_unless(curlErrCode == 1,
|
||||||
"Curl_llist_insert_next returned an error, Can't move on with test");
|
"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");
|
"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");
|
"Number of list elements is not as expected, Aborting");
|
||||||
|
|
||||||
/*actual testing code*/
|
/*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,
|
abort_unless(curlErrCode == 1,
|
||||||
"Curl_llist_move returned an error, Can't move on with test");
|
"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");
|
"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");
|
"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");
|
"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");
|
"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");
|
"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");
|
"llist_destination tail doesn't equal llist_destination head");
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user