llist: no longer uses malloc
The 'list element' struct now has to be within the data that is being added to the list. Removes 16.6% (tiny) mallocs from a simple HTTP transfer. (96 => 80) Also removed return codes since the llist functions can't fail now. Test 1300 updated accordingly. Closes #1435
This commit is contained in:
Родитель
cbb59ed9ce
Коммит
cbae73e1dd
|
@ -72,13 +72,11 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
|
||||||
|
|
||||||
/* Add a connection to a bundle */
|
/* Add a connection to a bundle */
|
||||||
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))
|
Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
|
||||||
return CURLE_OUT_OF_MEMORY;
|
&conn->bundle_node);
|
||||||
|
|
||||||
conn->bundle = cb_ptr;
|
conn->bundle = cb_ptr;
|
||||||
|
|
||||||
cb_ptr->num_connections++;
|
cb_ptr->num_connections++;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 - 2015, 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
|
||||||
|
@ -28,23 +28,19 @@
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
struct curl_fileinfo *Curl_fileinfo_alloc(void)
|
struct fileinfo *Curl_fileinfo_alloc(void)
|
||||||
{
|
{
|
||||||
struct curl_fileinfo *tmp = malloc(sizeof(struct curl_fileinfo));
|
return calloc(1, sizeof(struct fileinfo));
|
||||||
if(!tmp)
|
|
||||||
return NULL;
|
|
||||||
memset(tmp, 0, sizeof(struct curl_fileinfo));
|
|
||||||
return tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_fileinfo_dtor(void *user, void *element)
|
void Curl_fileinfo_dtor(void *user, void *element)
|
||||||
{
|
{
|
||||||
struct curl_fileinfo *finfo = element;
|
struct fileinfo *finfo = element;
|
||||||
(void) user;
|
(void) user;
|
||||||
if(!finfo)
|
if(!finfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Curl_safefree(finfo->b_data);
|
Curl_safefree(finfo->info.b_data);
|
||||||
|
|
||||||
free(finfo);
|
free(finfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 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
|
||||||
|
@ -23,11 +23,15 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
#include "llist.h"
|
||||||
|
|
||||||
struct curl_fileinfo *Curl_fileinfo_alloc(void);
|
struct fileinfo {
|
||||||
|
struct curl_fileinfo info;
|
||||||
|
struct curl_llist_element list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fileinfo *Curl_fileinfo_alloc(void);
|
||||||
|
|
||||||
void Curl_fileinfo_dtor(void *, void *);
|
void Curl_fileinfo_dtor(void *, void *);
|
||||||
|
|
||||||
struct curl_fileinfo *Curl_fileinfo_dup(const struct curl_fileinfo *src);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_FILEINFO_H */
|
#endif /* HEADER_CURL_FILEINFO_H */
|
||||||
|
|
|
@ -165,7 +165,7 @@ struct ftp_parselist_data {
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
CURLcode error;
|
CURLcode error;
|
||||||
struct curl_fileinfo *file_data;
|
struct fileinfo *file_data;
|
||||||
unsigned int item_length;
|
unsigned int item_length;
|
||||||
size_t item_offset;
|
size_t item_offset;
|
||||||
struct {
|
struct {
|
||||||
|
@ -275,7 +275,7 @@ static void PL_ERROR(struct connectdata *conn, CURLcode err)
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
||||||
struct curl_fileinfo *finfo)
|
struct fileinfo *infop)
|
||||||
{
|
{
|
||||||
curl_fnmatch_callback compare;
|
curl_fnmatch_callback compare;
|
||||||
struct WildcardData *wc = &conn->data->wildcard;
|
struct WildcardData *wc = &conn->data->wildcard;
|
||||||
|
@ -283,6 +283,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
||||||
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;
|
||||||
|
struct curl_fileinfo *finfo = &infop->info;
|
||||||
|
|
||||||
/* move finfo pointers to b_data */
|
/* move finfo pointers to b_data */
|
||||||
char *str = finfo->b_data;
|
char *str = finfo->b_data;
|
||||||
|
@ -316,11 +317,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(add) {
|
if(add) {
|
||||||
if(!Curl_llist_insert_next(llist, llist->tail, finfo)) {
|
Curl_llist_insert_next(llist, llist->tail, finfo, &infop->list);
|
||||||
Curl_fileinfo_dtor(NULL, finfo);
|
|
||||||
tmpdata->parser->file_data = NULL;
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Curl_fileinfo_dtor(NULL, finfo);
|
Curl_fileinfo_dtor(NULL, finfo);
|
||||||
|
@ -337,6 +334,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
struct connectdata *conn = (struct connectdata *)connptr;
|
struct connectdata *conn = (struct connectdata *)connptr;
|
||||||
struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
|
struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
|
||||||
struct ftp_parselist_data *parser = tmpdata->parser;
|
struct ftp_parselist_data *parser = tmpdata->parser;
|
||||||
|
struct fileinfo *infop;
|
||||||
struct curl_fileinfo *finfo;
|
struct curl_fileinfo *finfo;
|
||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
@ -366,17 +364,18 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
parser->error = CURLE_OUT_OF_MEMORY;
|
parser->error = CURLE_OUT_OF_MEMORY;
|
||||||
return bufflen;
|
return bufflen;
|
||||||
}
|
}
|
||||||
parser->file_data->b_data = malloc(FTP_BUFFER_ALLOCSIZE);
|
parser->file_data->info.b_data = malloc(FTP_BUFFER_ALLOCSIZE);
|
||||||
if(!parser->file_data->b_data) {
|
if(!parser->file_data->info.b_data) {
|
||||||
PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
|
PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
}
|
}
|
||||||
parser->file_data->b_size = FTP_BUFFER_ALLOCSIZE;
|
parser->file_data->info.b_size = FTP_BUFFER_ALLOCSIZE;
|
||||||
parser->item_offset = 0;
|
parser->item_offset = 0;
|
||||||
parser->item_length = 0;
|
parser->item_length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
finfo = parser->file_data;
|
infop = parser->file_data;
|
||||||
|
finfo = &infop->info;
|
||||||
finfo->b_data[finfo->b_used++] = c;
|
finfo->b_data[finfo->b_used++] = c;
|
||||||
|
|
||||||
if(finfo->b_used >= finfo->b_size - 1) {
|
if(finfo->b_used >= finfo->b_size - 1) {
|
||||||
|
@ -498,8 +497,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
}
|
}
|
||||||
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_PERM;
|
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM;
|
||||||
parser->file_data->perm = perm;
|
parser->file_data->info.perm = perm;
|
||||||
parser->offsets.perm = parser->item_offset;
|
parser->offsets.perm = parser->item_offset;
|
||||||
|
|
||||||
parser->item_length = 0;
|
parser->item_length = 0;
|
||||||
|
@ -530,8 +529,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||||
hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
|
hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
|
||||||
if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
|
if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
|
||||||
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
|
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
|
||||||
parser->file_data->hardlinks = hlinks;
|
parser->file_data->info.hardlinks = hlinks;
|
||||||
}
|
}
|
||||||
parser->item_length = 0;
|
parser->item_length = 0;
|
||||||
parser->item_offset = 0;
|
parser->item_offset = 0;
|
||||||
|
@ -613,8 +612,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10);
|
fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10);
|
||||||
if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
|
if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
|
||||||
fsize != CURL_OFF_T_MIN) {
|
fsize != CURL_OFF_T_MIN) {
|
||||||
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
|
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE;
|
||||||
parser->file_data->size = fsize;
|
parser->file_data->info.size = fsize;
|
||||||
}
|
}
|
||||||
parser->item_length = 0;
|
parser->item_length = 0;
|
||||||
parser->item_offset = 0;
|
parser->item_offset = 0;
|
||||||
|
@ -731,7 +730,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||||
parser->offsets.filename = parser->item_offset;
|
parser->offsets.filename = parser->item_offset;
|
||||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||||
result = ftp_pl_insert_finfo(conn, finfo);
|
result = ftp_pl_insert_finfo(conn, infop);
|
||||||
if(result) {
|
if(result) {
|
||||||
PL_ERROR(conn, result);
|
PL_ERROR(conn, result);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
|
@ -743,7 +742,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||||
parser->offsets.filename = parser->item_offset;
|
parser->offsets.filename = parser->item_offset;
|
||||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||||
result = ftp_pl_insert_finfo(conn, finfo);
|
result = ftp_pl_insert_finfo(conn, infop);
|
||||||
if(result) {
|
if(result) {
|
||||||
PL_ERROR(conn, result);
|
PL_ERROR(conn, result);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
|
@ -838,7 +837,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
else if(c == '\n') {
|
else if(c == '\n') {
|
||||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||||
parser->offsets.symlink_target = parser->item_offset;
|
parser->offsets.symlink_target = parser->item_offset;
|
||||||
result = ftp_pl_insert_finfo(conn, finfo);
|
result = ftp_pl_insert_finfo(conn, infop);
|
||||||
if(result) {
|
if(result) {
|
||||||
PL_ERROR(conn, result);
|
PL_ERROR(conn, result);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
|
@ -850,7 +849,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||||
parser->offsets.symlink_target = parser->item_offset;
|
parser->offsets.symlink_target = parser->item_offset;
|
||||||
result = ftp_pl_insert_finfo(conn, finfo);
|
result = ftp_pl_insert_finfo(conn, infop);
|
||||||
if(result) {
|
if(result) {
|
||||||
PL_ERROR(conn, result);
|
PL_ERROR(conn, result);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
|
@ -953,10 +952,10 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
return bufflen;
|
return bufflen;
|
||||||
}
|
}
|
||||||
/* correct file type */
|
/* correct file type */
|
||||||
parser->file_data->filetype = CURLFILETYPE_FILE;
|
parser->file_data->info.filetype = CURLFILETYPE_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
|
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE;
|
||||||
parser->item_length = 0;
|
parser->item_length = 0;
|
||||||
parser->state.NT.main = PL_WINNT_FILENAME;
|
parser->state.NT.main = PL_WINNT_FILENAME;
|
||||||
parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
|
parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
|
||||||
|
@ -983,7 +982,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
parser->offsets.filename = parser->item_offset;
|
parser->offsets.filename = parser->item_offset;
|
||||||
finfo->b_data[finfo->b_used - 1] = 0;
|
finfo->b_data[finfo->b_used - 1] = 0;
|
||||||
parser->offsets.filename = parser->item_offset;
|
parser->offsets.filename = parser->item_offset;
|
||||||
result = ftp_pl_insert_finfo(conn, finfo);
|
result = ftp_pl_insert_finfo(conn, infop);
|
||||||
if(result) {
|
if(result) {
|
||||||
PL_ERROR(conn, result);
|
PL_ERROR(conn, result);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
|
@ -995,7 +994,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||||
case PL_WINNT_FILENAME_WINEOL:
|
case PL_WINNT_FILENAME_WINEOL:
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
parser->offsets.filename = parser->item_offset;
|
parser->offsets.filename = parser->item_offset;
|
||||||
result = ftp_pl_insert_finfo(conn, finfo);
|
result = ftp_pl_insert_finfo(conn, infop);
|
||||||
if(result) {
|
if(result) {
|
||||||
PL_ERROR(conn, result);
|
PL_ERROR(conn, result);
|
||||||
return bufflen;
|
return bufflen;
|
||||||
|
|
14
lib/hash.c
14
lib/hash.c
|
@ -124,17 +124,9 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
|
||||||
|
|
||||||
he = mk_hash_element(key, key_len, p);
|
he = mk_hash_element(key, key_len, p);
|
||||||
if(he) {
|
if(he) {
|
||||||
if(Curl_llist_insert_next(l, l->tail, he)) {
|
Curl_llist_insert_next(l, l->tail, he, &he->list);
|
||||||
++h->size;
|
++h->size;
|
||||||
return p; /* return the new entry */
|
return p; /* return the new entry */
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Couldn't insert it, destroy the 'he' element and the key again. We
|
|
||||||
* don't call hash_element_dtor() since that would also call the
|
|
||||||
* "destructor" for the actual data 'p'. When we fail, we shall not touch
|
|
||||||
* that data.
|
|
||||||
*/
|
|
||||||
free(he);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL; /* failure */
|
return NULL; /* failure */
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct curl_hash {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct curl_hash_element {
|
struct curl_hash_element {
|
||||||
|
struct curl_llist_element list;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
size_t key_len;
|
size_t key_len;
|
||||||
char key[1]; /* allocated memory following the struct */
|
char key[1]; /* allocated memory following the struct */
|
||||||
|
|
34
lib/llist.c
34
lib/llist.c
|
@ -49,18 +49,17 @@ Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
||||||
* entry is NULL and the list already has elements, the new one will be
|
* entry is NULL and the list already has elements, the new one will be
|
||||||
* inserted first in the list.
|
* inserted first in the list.
|
||||||
*
|
*
|
||||||
|
* The 'ne' argument should be a pointer into the object to store.
|
||||||
|
*
|
||||||
* Returns: 1 on success and 0 on failure.
|
* Returns: 1 on success and 0 on failure.
|
||||||
*
|
*
|
||||||
* @unittest: 1300
|
* @unittest: 1300
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
|
Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
const void *p)
|
const void *p,
|
||||||
|
struct curl_llist_element *ne)
|
||||||
{
|
{
|
||||||
struct curl_llist_element *ne = malloc(sizeof(struct curl_llist_element));
|
|
||||||
if(!ne)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ne->ptr = (void *) p;
|
ne->ptr = (void *) p;
|
||||||
if(list->size == 0) {
|
if(list->size == 0) {
|
||||||
list->head = ne;
|
list->head = ne;
|
||||||
|
@ -87,19 +86,18 @@ Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
++list->size;
|
++list->size;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unittest: 1300
|
* @unittest: 1300
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
void *user)
|
void *user)
|
||||||
{
|
{
|
||||||
|
void *ptr;
|
||||||
if(e == NULL || list->size == 0)
|
if(e == NULL || list->size == 0)
|
||||||
return 1;
|
return;
|
||||||
|
|
||||||
if(e == list->head) {
|
if(e == list->head) {
|
||||||
list->head = e->next;
|
list->head = e->next;
|
||||||
|
@ -117,16 +115,16 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
e->next->prev = e->prev;
|
e->next->prev = e->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
list->dtor(user, e->ptr);
|
ptr = e->ptr;
|
||||||
|
|
||||||
e->ptr = NULL;
|
e->ptr = NULL;
|
||||||
e->prev = NULL;
|
e->prev = NULL;
|
||||||
e->next = NULL;
|
e->next = NULL;
|
||||||
|
|
||||||
free(e);
|
|
||||||
--list->size;
|
--list->size;
|
||||||
|
|
||||||
return 1;
|
/* call the dtor() last for when it actually frees the 'e' memory itself */
|
||||||
|
list->dtor(user, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -147,13 +145,13 @@ Curl_llist_count(struct curl_llist *list)
|
||||||
/*
|
/*
|
||||||
* @unittest: 1300
|
* @unittest: 1300
|
||||||
*/
|
*/
|
||||||
int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
|
void Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
struct curl_llist *to_list,
|
struct curl_llist *to_list,
|
||||||
struct curl_llist_element *to_e)
|
struct curl_llist_element *to_e)
|
||||||
{
|
{
|
||||||
/* Remove element from list */
|
/* Remove element from list */
|
||||||
if(e == NULL || list->size == 0)
|
if(e == NULL || list->size == 0)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if(e == list->head) {
|
if(e == list->head) {
|
||||||
list->head = e->next;
|
list->head = e->next;
|
||||||
|
@ -193,6 +191,4 @@ int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
++to_list->size;
|
++to_list->size;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
15
lib/llist.h
15
lib/llist.h
|
@ -29,7 +29,6 @@ typedef void (*curl_llist_dtor)(void *, void *);
|
||||||
|
|
||||||
struct curl_llist_element {
|
struct curl_llist_element {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
struct curl_llist_element *prev;
|
struct curl_llist_element *prev;
|
||||||
struct curl_llist_element *next;
|
struct curl_llist_element *next;
|
||||||
};
|
};
|
||||||
|
@ -37,21 +36,19 @@ struct curl_llist_element {
|
||||||
struct curl_llist {
|
struct curl_llist {
|
||||||
struct curl_llist_element *head;
|
struct curl_llist_element *head;
|
||||||
struct curl_llist_element *tail;
|
struct curl_llist_element *tail;
|
||||||
|
|
||||||
curl_llist_dtor dtor;
|
curl_llist_dtor dtor;
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Curl_llist_init(struct curl_llist *, 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 *,
|
void Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
|
||||||
const void *);
|
const void *, struct curl_llist_element *node);
|
||||||
int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
|
void Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
|
||||||
void *);
|
void *);
|
||||||
size_t Curl_llist_count(struct curl_llist *);
|
size_t Curl_llist_count(struct curl_llist *);
|
||||||
void Curl_llist_destroy(struct curl_llist *, void *);
|
void Curl_llist_destroy(struct curl_llist *, void *);
|
||||||
int Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
|
void Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
|
||||||
struct curl_llist *, struct curl_llist_element *);
|
struct curl_llist *, struct curl_llist_element *);
|
||||||
|
|
||||||
#endif /* HEADER_CURL_LLIST_H */
|
#endif /* HEADER_CURL_LLIST_H */
|
||||||
|
|
||||||
|
|
45
lib/multi.c
45
lib/multi.c
|
@ -280,9 +280,8 @@ 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))
|
Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg,
|
||||||
return CURLM_OUT_OF_MEMORY;
|
&msg->list);
|
||||||
|
|
||||||
return CURLM_OK;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1432,10 +1431,9 @@ 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))
|
Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
&data->connect_queue);
|
||||||
else
|
result = CURLE_OK;
|
||||||
result = CURLE_OK;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2483,7 +2481,10 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct time_node {
|
||||||
|
struct curl_llist_element list;
|
||||||
|
struct timeval time;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add_next_timeout()
|
* add_next_timeout()
|
||||||
|
@ -2504,13 +2505,16 @@ static CURLMcode add_next_timeout(struct timeval now,
|
||||||
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;
|
||||||
|
struct time_node *node = NULL;
|
||||||
|
|
||||||
/* move over the timeout list for this specific handle and remove all
|
/* move over the timeout list for this specific handle and remove all
|
||||||
timeouts that are now passed tense and store the next pending
|
timeouts that are now passed tense and store the next pending
|
||||||
timeout in *tv */
|
timeout in *tv */
|
||||||
for(e = list->head; e;) {
|
for(e = list->head; e;) {
|
||||||
struct curl_llist_element *n = e->next;
|
struct curl_llist_element *n = e->next;
|
||||||
time_t diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
|
time_t diff;
|
||||||
|
node = (struct time_node *)e->ptr;
|
||||||
|
diff = curlx_tvdiff(node->time, now);
|
||||||
if(diff <= 0)
|
if(diff <= 0)
|
||||||
/* remove outdated entry */
|
/* remove outdated entry */
|
||||||
Curl_llist_remove(list, e, NULL);
|
Curl_llist_remove(list, e, NULL);
|
||||||
|
@ -2528,7 +2532,7 @@ static CURLMcode add_next_timeout(struct timeval now,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* copy the first entry to 'tv' */
|
/* copy the first entry to 'tv' */
|
||||||
memcpy(tv, e->ptr, sizeof(*tv));
|
memcpy(tv, &node->time, sizeof(*tv));
|
||||||
|
|
||||||
/* remove first entry from list */
|
/* remove first entry from list */
|
||||||
Curl_llist_remove(list, e, NULL);
|
Curl_llist_remove(list, e, NULL);
|
||||||
|
@ -2879,21 +2883,21 @@ multi_addtimeout(struct curl_llist *timeoutlist,
|
||||||
struct timeval *stamp)
|
struct timeval *stamp)
|
||||||
{
|
{
|
||||||
struct curl_llist_element *e;
|
struct curl_llist_element *e;
|
||||||
struct timeval *timedup;
|
struct time_node *node;
|
||||||
struct curl_llist_element *prev = NULL;
|
struct curl_llist_element *prev = NULL;
|
||||||
|
|
||||||
timedup = malloc(sizeof(*timedup));
|
node = malloc(sizeof(struct time_node));
|
||||||
if(!timedup)
|
if(!node)
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* copy the timestamp */
|
/* copy the timestamp */
|
||||||
memcpy(timedup, stamp, sizeof(*timedup));
|
memcpy(&node->time, stamp, sizeof(*stamp));
|
||||||
|
|
||||||
if(Curl_llist_count(timeoutlist)) {
|
if(Curl_llist_count(timeoutlist)) {
|
||||||
/* find the correct spot in the list */
|
/* find the correct spot in the list */
|
||||||
for(e = timeoutlist->head; e; e = e->next) {
|
for(e = timeoutlist->head; e; e = e->next) {
|
||||||
struct timeval *checktime = e->ptr;
|
struct time_node *check = (struct time_node *)e->ptr;
|
||||||
time_t diff = curlx_tvdiff(*checktime, *timedup);
|
time_t diff = curlx_tvdiff(check->time, node->time);
|
||||||
if(diff > 0)
|
if(diff > 0)
|
||||||
break;
|
break;
|
||||||
prev = e;
|
prev = e;
|
||||||
|
@ -2903,11 +2907,7 @@ multi_addtimeout(struct curl_llist *timeoutlist,
|
||||||
/* else
|
/* else
|
||||||
this is the first timeout on the list */
|
this is the first timeout on the list */
|
||||||
|
|
||||||
if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
|
Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
|
||||||
free(timedup);
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CURLM_OK;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3044,8 +3044,9 @@ void Curl_expire_clear(struct Curl_easy *data)
|
||||||
infof(data, "Internal error clearing splay node = %d\n", rc);
|
infof(data, "Internal error clearing splay node = %d\n", rc);
|
||||||
|
|
||||||
/* flush the timeout list too */
|
/* flush the timeout list too */
|
||||||
while(list->size > 0)
|
while(list->size > 0) {
|
||||||
Curl_llist_remove(list, list->tail, NULL);
|
Curl_llist_remove(list, list->tail, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
infof(data, "Expire cleared\n");
|
infof(data, "Expire cleared\n");
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "conncache.h"
|
#include "conncache.h"
|
||||||
|
|
||||||
struct Curl_message {
|
struct Curl_message {
|
||||||
|
struct curl_llist_element list;
|
||||||
/* the 'CURLMsg' is the part that is visible to the external user */
|
/* the 'CURLMsg' is the part that is visible to the external user */
|
||||||
struct CURLMsg extmsg;
|
struct CURLMsg extmsg;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,16 +38,15 @@
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
struct site_blacklist_entry {
|
struct site_blacklist_entry {
|
||||||
char *hostname;
|
struct curl_llist_element list;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
|
char hostname[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void site_blacklist_llist_dtor(void *user, void *element)
|
static void site_blacklist_llist_dtor(void *user, void *element)
|
||||||
{
|
{
|
||||||
struct site_blacklist_entry *entry = element;
|
struct site_blacklist_entry *entry = element;
|
||||||
(void)user;
|
(void)user;
|
||||||
|
|
||||||
Curl_safefree(entry->hostname);
|
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +93,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data,
|
||||||
static CURLcode addHandleToPipeline(struct Curl_easy *data,
|
static CURLcode addHandleToPipeline(struct Curl_easy *data,
|
||||||
struct curl_llist *pipeline)
|
struct curl_llist *pipeline)
|
||||||
{
|
{
|
||||||
if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
|
Curl_llist_insert_next(pipeline, pipeline->tail, data,
|
||||||
return CURLE_OUT_OF_MEMORY;
|
&data->pipeline_queue);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,24 +201,17 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||||
|
|
||||||
/* Parse the URLs and populate the list */
|
/* Parse the URLs and populate the list */
|
||||||
while(*sites) {
|
while(*sites) {
|
||||||
char *hostname;
|
|
||||||
char *port;
|
char *port;
|
||||||
struct site_blacklist_entry *entry;
|
struct site_blacklist_entry *entry;
|
||||||
|
|
||||||
hostname = strdup(*sites);
|
entry = malloc(sizeof(struct site_blacklist_entry) + strlen(*sites));
|
||||||
if(!hostname) {
|
|
||||||
Curl_llist_destroy(list, NULL);
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = malloc(sizeof(struct site_blacklist_entry));
|
|
||||||
if(!entry) {
|
if(!entry) {
|
||||||
free(hostname);
|
|
||||||
Curl_llist_destroy(list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
strcpy(entry->hostname, *sites);
|
||||||
|
|
||||||
port = strchr(hostname, ':');
|
port = strchr(entry->hostname, ':');
|
||||||
if(port) {
|
if(port) {
|
||||||
*port = '\0';
|
*port = '\0';
|
||||||
port++;
|
port++;
|
||||||
|
@ -230,14 +222,7 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||||
entry->port = 80;
|
entry->port = 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->hostname = hostname;
|
Curl_llist_insert_next(list, list->tail, entry, &entry->list);
|
||||||
|
|
||||||
if(!Curl_llist_insert_next(list, list->tail, entry)) {
|
|
||||||
site_blacklist_llist_dtor(NULL, entry);
|
|
||||||
Curl_llist_destroy(list, NULL);
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
sites++;
|
sites++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,6 +259,11 @@ bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct blacklist_node {
|
||||||
|
struct curl_llist_element list;
|
||||||
|
char server_name[1];
|
||||||
|
};
|
||||||
|
|
||||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||||
struct curl_llist *list)
|
struct curl_llist *list)
|
||||||
{
|
{
|
||||||
|
@ -286,20 +276,18 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||||
|
|
||||||
/* Parse the URLs and populate the list */
|
/* Parse the URLs and populate the list */
|
||||||
while(*servers) {
|
while(*servers) {
|
||||||
char *server_name;
|
struct blacklist_node *n;
|
||||||
|
size_t len = strlen(*servers);
|
||||||
|
|
||||||
server_name = strdup(*servers);
|
n = malloc(sizeof(struct blacklist_node) + len);
|
||||||
if(!server_name) {
|
if(!n) {
|
||||||
Curl_llist_destroy(list, NULL);
|
Curl_llist_destroy(list, NULL);
|
||||||
return CURLM_OUT_OF_MEMORY;
|
return CURLM_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
strcpy(n->server_name, *servers);
|
||||||
|
|
||||||
if(!Curl_llist_insert_next(list, list->tail, server_name)) {
|
Curl_llist_insert_next(list, list->tail, n->server_name,
|
||||||
Curl_llist_destroy(list, NULL);
|
&n->list);
|
||||||
Curl_safefree(server_name);
|
|
||||||
return CURLM_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
servers++;
|
servers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -898,6 +898,8 @@ struct connectdata {
|
||||||
connection is used! */
|
connection is used! */
|
||||||
struct Curl_easy *data;
|
struct Curl_easy *data;
|
||||||
|
|
||||||
|
struct curl_llist_element bundle_node; /* conncache */
|
||||||
|
|
||||||
/* chunk is for HTTP chunked encoding, but is in the general connectdata
|
/* chunk is for HTTP chunked encoding, but is in the general connectdata
|
||||||
struct only because we can do just about any protocol through a HTTP proxy
|
struct only because we can do just about any protocol through a HTTP proxy
|
||||||
and a HTTP proxy may in fact respond using chunked encoding */
|
and a HTTP proxy may in fact respond using chunked encoding */
|
||||||
|
@ -1804,6 +1806,8 @@ struct Curl_easy {
|
||||||
struct Curl_easy *prev;
|
struct Curl_easy *prev;
|
||||||
|
|
||||||
struct connectdata *easy_conn; /* the "unit's" connection */
|
struct connectdata *easy_conn; /* the "unit's" connection */
|
||||||
|
struct curl_llist_element connect_queue;
|
||||||
|
struct curl_llist_element pipeline_queue;
|
||||||
|
|
||||||
CURLMstate mstate; /* the handle's state */
|
CURLMstate mstate; /* the handle's state */
|
||||||
CURLcode result; /* previous result */
|
CURLcode result; /* previous result */
|
||||||
|
|
|
@ -48,15 +48,20 @@ static void unit_stop(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
UNITTEST_START
|
UNITTEST_START
|
||||||
|
{
|
||||||
int unusedData_case1 = 1;
|
int unusedData_case1 = 1;
|
||||||
int unusedData_case2 = 2;
|
int unusedData_case2 = 2;
|
||||||
int unusedData_case3 = 3;
|
int unusedData_case3 = 3;
|
||||||
|
struct curl_llist_element case1_list;
|
||||||
|
struct curl_llist_element case2_list;
|
||||||
|
struct curl_llist_element case3_list;
|
||||||
|
struct curl_llist_element case4_list;
|
||||||
|
struct curl_llist_element case5_list;
|
||||||
struct curl_llist_element *head;
|
struct curl_llist_element *head;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testing llist_init
|
* testing llist_init
|
||||||
|
@ -85,67 +90,49 @@ 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);
|
Curl_llist_insert_next(&llist, llist.head, &unusedData_case1, &case1_list);
|
||||||
if(curlErrCode == 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,
|
|
||||||
"List size should be 1 after adding a new element");
|
|
||||||
/*same goes for the list tail */
|
|
||||||
fail_unless(llist.tail == llist.head,
|
|
||||||
"List size should be 1 after adding a new element");
|
|
||||||
|
|
||||||
/**
|
fail_unless(Curl_llist_count(&llist) == 1,
|
||||||
* testing Curl_llist_insert_next
|
"List size should be 1 after adding a new element");
|
||||||
* case 2:
|
/*test that the list head data holds my unusedData */
|
||||||
* list has 1 element, adding one element after the head
|
fail_unless(llist.head->ptr == &unusedData_case1,
|
||||||
* @assumptions:
|
"head ptr should be first entry");
|
||||||
* 1: the element next to head should be our newly created element
|
/*same goes for the list tail */
|
||||||
* 2: the list tail should be our newly created element
|
fail_unless(llist.tail == llist.head,
|
||||||
*/
|
"tail and head should be the same");
|
||||||
|
|
||||||
curlErrCode = Curl_llist_insert_next(&llist, llist.head,
|
/**
|
||||||
&unusedData_case3);
|
* testing Curl_llist_insert_next
|
||||||
if(curlErrCode == 1) {
|
* case 2:
|
||||||
fail_unless(llist.head->next->ptr == &unusedData_case3,
|
* list has 1 element, adding one element after the head
|
||||||
"the node next to head is not getting set correctly");
|
* @assumptions:
|
||||||
fail_unless(llist.tail->ptr == &unusedData_case3,
|
* 1: the element next to head should be our newly created element
|
||||||
"the list tail is not getting set correctly");
|
* 2: the list tail should be our newly created element
|
||||||
}
|
*/
|
||||||
else {
|
|
||||||
printf("skipping Curl_llist_insert_next as a non "
|
|
||||||
"success error code was returned\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
Curl_llist_insert_next(&llist, llist.head,
|
||||||
* testing Curl_llist_insert_next
|
&unusedData_case3, &case3_list);
|
||||||
* case 3:
|
fail_unless(llist.head->next->ptr == &unusedData_case3,
|
||||||
* list has >1 element, adding one element after "NULL"
|
"the node next to head is not getting set correctly");
|
||||||
* @assumptions:
|
fail_unless(llist.tail->ptr == &unusedData_case3,
|
||||||
* 1: the element next to head should be our newly created element
|
"the list tail is not getting set correctly");
|
||||||
* 2: the list tail should different from newly created element
|
|
||||||
*/
|
|
||||||
|
|
||||||
curlErrCode = Curl_llist_insert_next(&llist, llist.head,
|
/**
|
||||||
&unusedData_case2);
|
* testing Curl_llist_insert_next
|
||||||
if(curlErrCode == 1) {
|
* case 3:
|
||||||
fail_unless(llist.head->next->ptr == &unusedData_case2,
|
* list has >1 element, adding one element after "NULL"
|
||||||
"the node next to head is not getting set correctly");
|
* @assumptions:
|
||||||
/* better safe than sorry, check that the tail isn't corrupted */
|
* 1: the element next to head should be our newly created element
|
||||||
fail_unless(llist.tail->ptr != &unusedData_case2,
|
* 2: the list tail should different from newly created element
|
||||||
"the list tail is not getting set correctly");
|
*/
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("skipping Curl_llist_insert_next as a non "
|
|
||||||
"success error code was returned\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
Curl_llist_insert_next(&llist, llist.head,
|
||||||
else {
|
&unusedData_case2, &case2_list);
|
||||||
printf("skipping Curl_llist_insert_next as a non "
|
fail_unless(llist.head->next->ptr == &unusedData_case2,
|
||||||
"success error code was returned\n");
|
"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,
|
||||||
|
"the list tail is not getting set correctly");
|
||||||
|
|
||||||
/* unit tests for Curl_llist_remove */
|
/* unit tests for Curl_llist_remove */
|
||||||
|
|
||||||
|
@ -183,8 +170,11 @@ 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,
|
||||||
|
&case4_list);
|
||||||
llist_size = Curl_llist_count(&llist);
|
llist_size = Curl_llist_count(&llist);
|
||||||
|
fail_unless(llist_size == 3, "should be 3 list members");
|
||||||
|
|
||||||
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;
|
||||||
|
@ -248,20 +238,17 @@ UNITTEST_START
|
||||||
* add one element to the list
|
* add one element to the list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
curlErrCode = Curl_llist_insert_next(&llist, llist.head, &unusedData_case1);
|
Curl_llist_insert_next(&llist, llist.head, &unusedData_case1,
|
||||||
|
&case5_list);
|
||||||
/* necessary assertions */
|
/* 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");
|
"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);
|
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");
|
"moving element from llist didn't decrement the size");
|
||||||
|
|
||||||
|
@ -279,7 +266,5 @@ UNITTEST_START
|
||||||
|
|
||||||
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UNITTEST_STOP
|
UNITTEST_STOP
|
||||||
|
|
Загрузка…
Ссылка в новой задаче