Skip to content

Commit cbae73e

Browse files
committedApr 22, 2017
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
1 parent cbb59ed commit cbae73e

File tree

13 files changed

+170
-208
lines changed

13 files changed

+170
-208
lines changed
 

‎lib/conncache.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,11 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
7272

7373
/* Add a connection to a bundle */
7474
static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
75-
struct connectdata *conn)
75+
struct connectdata *conn)
7676
{
77-
if(!Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn))
78-
return CURLE_OUT_OF_MEMORY;
79-
77+
Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
78+
&conn->bundle_node);
8079
conn->bundle = cb_ptr;
81-
8280
cb_ptr->num_connections++;
8381
return CURLE_OK;
8482
}

‎lib/fileinfo.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* | (__| |_| | _ <| |___
66
* \___|\___/|_| \_\_____|
77
*
8-
* Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
8+
* Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
99
*
1010
* This software is licensed as described in the file COPYING, which
1111
* you should have received as part of this distribution. The terms
@@ -28,23 +28,19 @@
2828
/* The last #include file should be: */
2929
#include "memdebug.h"
3030

31-
struct curl_fileinfo *Curl_fileinfo_alloc(void)
31+
struct fileinfo *Curl_fileinfo_alloc(void)
3232
{
33-
struct curl_fileinfo *tmp = malloc(sizeof(struct curl_fileinfo));
34-
if(!tmp)
35-
return NULL;
36-
memset(tmp, 0, sizeof(struct curl_fileinfo));
37-
return tmp;
33+
return calloc(1, sizeof(struct fileinfo));
3834
}
3935

4036
void Curl_fileinfo_dtor(void *user, void *element)
4137
{
42-
struct curl_fileinfo *finfo = element;
38+
struct fileinfo *finfo = element;
4339
(void) user;
4440
if(!finfo)
4541
return;
4642

47-
Curl_safefree(finfo->b_data);
43+
Curl_safefree(finfo->info.b_data);
4844

4945
free(finfo);
5046
}

‎lib/fileinfo.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* | (__| |_| | _ <| |___
88
* \___|\___/|_| \_\_____|
99
*
10-
* Copyright (C) 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
10+
* Copyright (C) 2010, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
1111
*
1212
* This software is licensed as described in the file COPYING, which
1313
* you should have received as part of this distribution. The terms
@@ -23,11 +23,15 @@
2323
***************************************************************************/
2424

2525
#include <curl/curl.h>
26+
#include "llist.h"
2627

27-
struct curl_fileinfo *Curl_fileinfo_alloc(void);
28+
struct fileinfo {
29+
struct curl_fileinfo info;
30+
struct curl_llist_element list;
31+
};
2832

29-
void Curl_fileinfo_dtor(void *, void *);
33+
struct fileinfo *Curl_fileinfo_alloc(void);
3034

31-
struct curl_fileinfo *Curl_fileinfo_dup(const struct curl_fileinfo *src);
35+
void Curl_fileinfo_dtor(void *, void *);
3236

3337
#endif /* HEADER_CURL_FILEINFO_H */

‎lib/ftplistparser.c

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ struct ftp_parselist_data {
165165
} state;
166166

167167
CURLcode error;
168-
struct curl_fileinfo *file_data;
168+
struct fileinfo *file_data;
169169
unsigned int item_length;
170170
size_t item_offset;
171171
struct {
@@ -275,14 +275,15 @@ static void PL_ERROR(struct connectdata *conn, CURLcode err)
275275
}
276276

277277
static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
278-
struct curl_fileinfo *finfo)
278+
struct fileinfo *infop)
279279
{
280280
curl_fnmatch_callback compare;
281281
struct WildcardData *wc = &conn->data->wildcard;
282282
struct ftp_wc_tmpdata *tmpdata = wc->tmp;
283283
struct curl_llist *llist = &wc->filelist;
284284
struct ftp_parselist_data *parser = tmpdata->parser;
285285
bool add = TRUE;
286+
struct curl_fileinfo *finfo = &infop->info;
286287

287288
/* move finfo pointers to b_data */
288289
char *str = finfo->b_data;
@@ -316,11 +317,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
316317
}
317318

318319
if(add) {
319-
if(!Curl_llist_insert_next(llist, llist->tail, finfo)) {
320-
Curl_fileinfo_dtor(NULL, finfo);
321-
tmpdata->parser->file_data = NULL;
322-
return CURLE_OUT_OF_MEMORY;
323-
}
320+
Curl_llist_insert_next(llist, llist->tail, finfo, &infop->list);
324321
}
325322
else {
326323
Curl_fileinfo_dtor(NULL, finfo);
@@ -337,6 +334,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
337334
struct connectdata *conn = (struct connectdata *)connptr;
338335
struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
339336
struct ftp_parselist_data *parser = tmpdata->parser;
337+
struct fileinfo *infop;
340338
struct curl_fileinfo *finfo;
341339
unsigned long i = 0;
342340
CURLcode result;
@@ -366,17 +364,18 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
366364
parser->error = CURLE_OUT_OF_MEMORY;
367365
return bufflen;
368366
}
369-
parser->file_data->b_data = malloc(FTP_BUFFER_ALLOCSIZE);
370-
if(!parser->file_data->b_data) {
367+
parser->file_data->info.b_data = malloc(FTP_BUFFER_ALLOCSIZE);
368+
if(!parser->file_data->info.b_data) {
371369
PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
372370
return bufflen;
373371
}
374-
parser->file_data->b_size = FTP_BUFFER_ALLOCSIZE;
372+
parser->file_data->info.b_size = FTP_BUFFER_ALLOCSIZE;
375373
parser->item_offset = 0;
376374
parser->item_length = 0;
377375
}
378376

379-
finfo = parser->file_data;
377+
infop = parser->file_data;
378+
finfo = &infop->info;
380379
finfo->b_data[finfo->b_used++] = c;
381380

382381
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,
498497
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
499498
return bufflen;
500499
}
501-
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_PERM;
502-
parser->file_data->perm = perm;
500+
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM;
501+
parser->file_data->info.perm = perm;
503502
parser->offsets.perm = parser->item_offset;
504503

505504
parser->item_length = 0;
@@ -530,8 +529,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
530529
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
531530
hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
532531
if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
533-
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
534-
parser->file_data->hardlinks = hlinks;
532+
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
533+
parser->file_data->info.hardlinks = hlinks;
535534
}
536535
parser->item_length = 0;
537536
parser->item_offset = 0;
@@ -613,8 +612,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
613612
fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10);
614613
if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
615614
fsize != CURL_OFF_T_MIN) {
616-
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
617-
parser->file_data->size = fsize;
615+
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE;
616+
parser->file_data->info.size = fsize;
618617
}
619618
parser->item_length = 0;
620619
parser->item_offset = 0;
@@ -731,7 +730,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
731730
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
732731
parser->offsets.filename = parser->item_offset;
733732
parser->state.UNIX.main = PL_UNIX_FILETYPE;
734-
result = ftp_pl_insert_finfo(conn, finfo);
733+
result = ftp_pl_insert_finfo(conn, infop);
735734
if(result) {
736735
PL_ERROR(conn, result);
737736
return bufflen;
@@ -743,7 +742,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
743742
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
744743
parser->offsets.filename = parser->item_offset;
745744
parser->state.UNIX.main = PL_UNIX_FILETYPE;
746-
result = ftp_pl_insert_finfo(conn, finfo);
745+
result = ftp_pl_insert_finfo(conn, infop);
747746
if(result) {
748747
PL_ERROR(conn, result);
749748
return bufflen;
@@ -838,7 +837,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
838837
else if(c == '\n') {
839838
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
840839
parser->offsets.symlink_target = parser->item_offset;
841-
result = ftp_pl_insert_finfo(conn, finfo);
840+
result = ftp_pl_insert_finfo(conn, infop);
842841
if(result) {
843842
PL_ERROR(conn, result);
844843
return bufflen;
@@ -850,7 +849,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
850849
if(c == '\n') {
851850
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
852851
parser->offsets.symlink_target = parser->item_offset;
853-
result = ftp_pl_insert_finfo(conn, finfo);
852+
result = ftp_pl_insert_finfo(conn, infop);
854853
if(result) {
855854
PL_ERROR(conn, result);
856855
return bufflen;
@@ -953,10 +952,10 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
953952
return bufflen;
954953
}
955954
/* correct file type */
956-
parser->file_data->filetype = CURLFILETYPE_FILE;
955+
parser->file_data->info.filetype = CURLFILETYPE_FILE;
957956
}
958957

959-
parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
958+
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE;
960959
parser->item_length = 0;
961960
parser->state.NT.main = PL_WINNT_FILENAME;
962961
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,
983982
parser->offsets.filename = parser->item_offset;
984983
finfo->b_data[finfo->b_used - 1] = 0;
985984
parser->offsets.filename = parser->item_offset;
986-
result = ftp_pl_insert_finfo(conn, finfo);
985+
result = ftp_pl_insert_finfo(conn, infop);
987986
if(result) {
988987
PL_ERROR(conn, result);
989988
return bufflen;
@@ -995,7 +994,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
995994
case PL_WINNT_FILENAME_WINEOL:
996995
if(c == '\n') {
997996
parser->offsets.filename = parser->item_offset;
998-
result = ftp_pl_insert_finfo(conn, finfo);
997+
result = ftp_pl_insert_finfo(conn, infop);
999998
if(result) {
1000999
PL_ERROR(conn, result);
10011000
return bufflen;

‎lib/hash.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,9 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
124124

125125
he = mk_hash_element(key, key_len, p);
126126
if(he) {
127-
if(Curl_llist_insert_next(l, l->tail, he)) {
128-
++h->size;
129-
return p; /* return the new entry */
130-
}
131-
/*
132-
* Couldn't insert it, destroy the 'he' element and the key again. We
133-
* don't call hash_element_dtor() since that would also call the
134-
* "destructor" for the actual data 'p'. When we fail, we shall not touch
135-
* that data.
136-
*/
137-
free(he);
127+
Curl_llist_insert_next(l, l->tail, he, &he->list);
128+
++h->size;
129+
return p; /* return the new entry */
138130
}
139131

140132
return NULL; /* failure */

‎lib/hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct curl_hash {
5757
};
5858

5959
struct curl_hash_element {
60+
struct curl_llist_element list;
6061
void *ptr;
6162
size_t key_len;
6263
char key[1]; /* allocated memory following the struct */

‎lib/llist.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,17 @@ Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
4949
* entry is NULL and the list already has elements, the new one will be
5050
* inserted first in the list.
5151
*
52+
* The 'ne' argument should be a pointer into the object to store.
53+
*
5254
* Returns: 1 on success and 0 on failure.
5355
*
5456
* @unittest: 1300
5557
*/
56-
int
58+
void
5759
Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
58-
const void *p)
60+
const void *p,
61+
struct curl_llist_element *ne)
5962
{
60-
struct curl_llist_element *ne = malloc(sizeof(struct curl_llist_element));
61-
if(!ne)
62-
return 0;
63-
6463
ne->ptr = (void *) p;
6564
if(list->size == 0) {
6665
list->head = ne;
@@ -87,19 +86,18 @@ Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
8786
}
8887

8988
++list->size;
90-
91-
return 1;
9289
}
9390

9491
/*
9592
* @unittest: 1300
9693
*/
97-
int
94+
void
9895
Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
9996
void *user)
10097
{
98+
void *ptr;
10199
if(e == NULL || list->size == 0)
102-
return 1;
100+
return;
103101

104102
if(e == list->head) {
105103
list->head = e->next;
@@ -117,16 +115,16 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
117115
e->next->prev = e->prev;
118116
}
119117

120-
list->dtor(user, e->ptr);
118+
ptr = e->ptr;
121119

122120
e->ptr = NULL;
123121
e->prev = NULL;
124122
e->next = NULL;
125123

126-
free(e);
127124
--list->size;
128125

129-
return 1;
126+
/* call the dtor() last for when it actually frees the 'e' memory itself */
127+
list->dtor(user, ptr);
130128
}
131129

132130
void
@@ -147,13 +145,13 @@ Curl_llist_count(struct curl_llist *list)
147145
/*
148146
* @unittest: 1300
149147
*/
150-
int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
151-
struct curl_llist *to_list,
152-
struct curl_llist_element *to_e)
148+
void Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
149+
struct curl_llist *to_list,
150+
struct curl_llist_element *to_e)
153151
{
154152
/* Remove element from list */
155153
if(e == NULL || list->size == 0)
156-
return 0;
154+
return;
157155

158156
if(e == list->head) {
159157
list->head = e->next;
@@ -193,6 +191,4 @@ int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
193191
}
194192

195193
++to_list->size;
196-
197-
return 1;
198194
}

0 commit comments

Comments
 (0)