diff --git a/include/list.h b/include/list.h index b9b6f7442..4e7568521 100644 --- a/include/list.h +++ b/include/list.h @@ -16,17 +16,17 @@ #ifndef _LIST_H_ #define _LIST_H_ +#include #include #define LIST_CHUNKSIZE 16 /** Static list initialization */ -#define LIST_INIT(dtor) { \ +#define LIST_INIT() { \ .array = NULL, \ .length = 0, \ .capacity = 0, \ - .lock = PTHREAD_MUTEX_INITIALIZER, \ - .destructor = dtor \ + .lock = PTHREAD_MUTEX_INITIALIZER \ } #define list_length(list) ((list)->length) @@ -51,19 +51,22 @@ struct list { void **array; /**< Array of pointers to list elements */ size_t capacity; /**< Size of list::array in elements */ size_t length; /**< Number of elements of list::array which are in use */ - dtor_cb_t destructor; /**< A destructor which gets called for every list elements during list_destroy() */ pthread_mutex_t lock; /**< A mutex to allow thread-safe accesses */ }; /** Initialize a list. * * @param l A pointer to the list data structure. - * @param dtor A function pointer to a desctructor which will be called for every list item when the list is destroyed. */ -void list_init(struct list *l, dtor_cb_t dtor); +void list_init(struct list *l); -/** Destroy a list and call destructors for all list elements */ -void list_destroy(struct list *l); +/** Destroy a list and call destructors for all list elements + * + * @param free free() all list members during when calling list_destroy() + * @param dtor A function pointer to a desctructor which will be called for every list item when the list is destroyed. + * @param l A pointer to the list data structure. + */ +void list_destroy(struct list *l, dtor_cb_t dtor, bool free); /** Append an element to the end of the list */ void list_push(struct list *l, void *p); diff --git a/lib/if.c b/lib/if.c index 11df748ce..b86d8a767 100644 --- a/lib/if.c +++ b/lib/if.c @@ -37,7 +37,7 @@ struct interface * if_create(struct rtnl_link *link) else warn("Did not found any interrupts for interface '%s'", rtnl_link_get_name(i->nl_link)); - list_init(&i->sockets, NULL); + list_init(&i->sockets); return i; } @@ -45,7 +45,7 @@ struct interface * if_create(struct rtnl_link *link) void if_destroy(struct interface *i) { /* List members are freed by the nodes they belong to. */ - list_destroy(&i->sockets); + list_destroy(&i->sockets, NULL, false); rtnl_qdisc_put(i->tc_qdisc); diff --git a/lib/list.c b/lib/list.c index c083c0f7a..55be8c7ba 100644 --- a/lib/list.c +++ b/lib/list.c @@ -32,24 +32,25 @@ static int cmp_sort(const void *a, const void *b, void *thunk) { return cmp(*(void **) a, *(void **) b); } -void list_init(struct list *l, dtor_cb_t dtor) +void list_init(struct list *l) { pthread_mutex_init(&l->lock, NULL); - l->destructor = dtor; l->length = 0; l->capacity = 0; l->array = NULL; } -void list_destroy(struct list *l) +void list_destroy(struct list *l, dtor_cb_t destructor, bool release) { pthread_mutex_lock(&l->lock); - if (l->destructor) { - list_foreach(void *p, l) - l->destructor(p); + list_foreach(void *p, l) { + if (destructor) + destructor(p); + if (release) + free(p); } free(l->array); diff --git a/lib/socket.c b/lib/socket.c index fc294ea6d..3f90c82bd 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -44,7 +44,7 @@ int socket_init(int argc, char * argv[], config_setting_t *cfg) error("The 'socket' node-type requires superuser privileges!"); nl_init(); /* Fill link cache */ - list_init(&interfaces, (dtor_cb_t) if_destroy); + list_init(&interfaces); /* Gather list of used network interfaces */ list_foreach(struct node *n, &vt.instances) { @@ -88,7 +88,7 @@ int socket_deinit() list_foreach(struct interface *i, &interfaces) if_stop(i); - list_destroy(&interfaces); + list_destroy(&interfaces, (dtor_cb_t) if_destroy, false); return 0; } diff --git a/src/pipe.c b/src/pipe.c index 4e0556094..d08f9155b 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -48,7 +48,7 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx) pool_destroy(&recv_pool); pool_destroy(&send_pool); - list_destroy(&nodes); + list_destroy(&nodes, (dtor_cb_t) node_destroy, false); info(GRN("Goodbye!")); exit(EXIT_SUCCESS); @@ -149,7 +149,7 @@ int main(int argc, char *argv[]) config_t config; /* Create lists */ - list_init(&nodes, (dtor_cb_t) node_destroy); + list_init(&nodes); log_init(); config_init(&config); diff --git a/src/server.c b/src/server.c index 4fed6eee5..afb8d26c4 100644 --- a/src/server.c +++ b/src/server.c @@ -49,8 +49,8 @@ static void quit() } /* Freeing dynamically allocated memory */ - list_destroy(&paths); - list_destroy(&nodes); + list_destroy(&paths, (dtor_cb_t) path_destroy, false); + list_destroy(&nodes, (dtor_cb_t) node_destroy, false); config_destroy(&config); info(GRN("Goodbye!")); @@ -142,8 +142,8 @@ int main(int argc, char *argv[]) error("Your kernel version is to old: required >= %u.%u", KERNEL_VERSION_MAJ, KERNEL_VERSION_MIN); /* Initialize lists */ - list_init(&paths, (dtor_cb_t) path_destroy); - list_init(&nodes, (dtor_cb_t) node_destroy); + list_init(&paths); + list_init(&nodes); info("Parsing configuration"); { INDENT diff --git a/src/test.c b/src/test.c index 9430a9176..a5bb2946a 100644 --- a/src/test.c +++ b/src/test.c @@ -81,6 +81,8 @@ int main(int argc, char *argv[]) sigemptyset(&sa_quit.sa_mask); sigaction(SIGTERM, &sa_quit, NULL); sigaction(SIGINT, &sa_quit, NULL); + + list_init(&nodes); log_init(); config_init(&config); @@ -138,7 +140,7 @@ check: if (optarg == endptr) node_stop(node); node_deinit(node->_vt); - list_destroy(&nodes); + list_destroy(&nodes, node_destroy, false); config_destroy(&config); return 0;