commit f4d00645ed078f4e8ddd883d37303e517d605bc8
parent 1f5e482b8a62445879daa102a958a916f8e094cf
Author: Joris Vink <joris@coders.se>
Date: Mon, 1 Feb 2016 19:51:27 +0100
Merge pull request #99 from oneswig/master
Add resource management as part of the kore shutdown process.
Diffstat:
18 files changed, 230 insertions(+), 6 deletions(-)
diff --git a/includes/http.h b/includes/http.h
@@ -211,6 +211,7 @@ extern char *http_body_disk_path;
void kore_accesslog(struct http_request *);
void http_init(void);
+void http_cleanup(void);
void http_process(void);
const char *http_status_text(int);
time_t http_date_to_time(char *);
diff --git a/includes/kore.h b/includes/kore.h
@@ -42,6 +42,7 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
+#include <stdarg.h>
#if defined(__cplusplus)
extern "C" {
@@ -433,6 +434,7 @@ struct kore_worker *kore_worker_data(u_int8_t);
void kore_platform_init(void);
void kore_platform_event_init(void);
+void kore_platform_event_cleanup(void);
void kore_platform_proctitle(char *);
void kore_platform_disable_read(int);
void kore_platform_enable_accept(void);
@@ -468,6 +470,7 @@ void kore_tls_info_callback(const SSL *, int, int);
#endif
void kore_connection_init(void);
+void kore_connection_cleanup(void);
void kore_connection_prune(int);
struct connection *kore_connection_new(void *);
void kore_connection_check_timeout(void);
@@ -496,6 +499,7 @@ void *kore_pool_get(struct kore_pool *);
void kore_pool_put(struct kore_pool *, void *);
void kore_pool_init(struct kore_pool *, const char *,
u_int32_t, u_int32_t);
+void kore_pool_cleanup(struct kore_pool *);
time_t kore_date_to_time(char *);
char *kore_time_to_date(time_t);
@@ -531,7 +535,9 @@ int kore_msg_register(u_int8_t,
void (*cb)(struct kore_msg *, const void *));
void kore_domain_init(void);
+void kore_domain_cleanup(void);
int kore_domain_new(char *);
+void kore_domain_free(struct kore_domain *);
void kore_module_init(void);
void kore_module_reload(int);
void kore_module_onload(void);
@@ -543,6 +549,7 @@ void kore_module_load(const char *, const char *);
void kore_domain_sslstart(struct kore_domain *);
int kore_module_handler_new(const char *, const char *,
const char *, const char *, int);
+void kore_module_handler_free(struct kore_module_handle *);
struct kore_domain *kore_domain_lookup(const char *);
struct kore_module_handle *kore_module_handler_find(const char *,
@@ -569,6 +576,7 @@ void net_write32(u_int8_t *, u_int32_t);
void net_write64(u_int8_t *, u_int64_t);
void net_init(void);
+void net_cleanup(void);
int net_send(struct connection *);
int net_send_flush(struct connection *);
int net_recv_flush(struct connection *);
diff --git a/src/bsd.c b/src/bsd.c
@@ -22,6 +22,9 @@
#include <sys/cpuset.h>
#endif
+#include <errno.h>
+#include <string.h>
+
#include "kore.h"
#if defined(KORE_USE_PGSQL)
@@ -91,6 +94,20 @@ kore_platform_event_init(void)
}
}
+void
+kore_platform_event_cleanup(void)
+{
+ if (kfd >= 0) {
+ close(kfd);
+ kfd = -1;
+ }
+
+ if (events != NULL) {
+ kore_mem_free(events);
+ events = NULL;
+ }
+}
+
int
kore_platform_event_wait(u_int64_t timer)
{
diff --git a/src/buf.c b/src/buf.c
@@ -14,6 +14,11 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
#include "kore.h"
struct kore_buf *
diff --git a/src/cli.c b/src/cli.c
@@ -20,6 +20,7 @@
#include <sys/queue.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/time.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
diff --git a/src/config.c b/src/config.c
@@ -16,6 +16,8 @@
#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <fcntl.h>
diff --git a/src/connection.c b/src/connection.c
@@ -38,6 +38,16 @@ kore_connection_init(void)
sizeof(struct connection), worker_max_connections);
}
+void
+kore_connection_cleanup(void)
+{
+ kore_debug("connection_cleanup()");
+
+ /* Drop all connections */
+ kore_connection_prune(KORE_CONNECTION_PRUNE_ALL);
+ kore_pool_cleanup(&connection_pool);
+}
+
struct connection *
kore_connection_new(void *owner)
{
diff --git a/src/domain.c b/src/domain.c
@@ -42,6 +42,17 @@ kore_domain_init(void)
TAILQ_INIT(&domains);
}
+void
+kore_domain_cleanup(void)
+{
+ struct kore_domain *dom;
+
+ while ((dom=TAILQ_FIRST(&domains)) != NULL) {
+ TAILQ_REMOVE(&domains, dom, list);
+ kore_domain_free(dom);
+ }
+}
+
int
kore_domain_new(char *domain)
{
@@ -72,6 +83,49 @@ kore_domain_new(char *domain)
}
void
+kore_domain_free(struct kore_domain *dom)
+{
+ struct kore_module_handle *hdlr;
+
+ if (dom != NULL) {
+
+ if (primary_dom == dom) {
+ primary_dom = NULL;
+ }
+ TAILQ_REMOVE(&domains, dom, list);
+
+ if (dom->domain != NULL) {
+ kore_mem_free(dom->domain);
+ }
+
+#if !defined(KORE_NO_TLS)
+ if (dom->ssl_ctx != NULL) {
+ SSL_CTX_free(dom->ssl_ctx);
+ }
+ if (dom->cafile != NULL) {
+ kore_mem_free(dom->cafile);
+ }
+ if (dom->certkey != NULL) {
+ kore_mem_free(dom->certkey);
+ }
+ if (dom->certfile != NULL) {
+ kore_mem_free(dom->certfile);
+ }
+ if (dom->crlfile != NULL) {
+ kore_mem_free(dom->crlfile);
+ }
+#endif
+
+ /* Drop all handlers associated with this domain */
+ while ((hdlr=TAILQ_FIRST(&(dom->handlers))) != NULL) {
+ TAILQ_REMOVE(&(dom->handlers), hdlr, list);
+ kore_module_handler_free(hdlr);
+ }
+ kore_mem_free(dom);
+ }
+}
+
+void
kore_domain_sslstart(struct kore_domain *dom)
{
#if !defined(KORE_NO_TLS)
@@ -179,7 +233,9 @@ kore_domain_sslstart(struct kore_domain *dom)
SSL_CTX_set_tlsext_servername_callback(dom->ssl_ctx, kore_tls_sni_cb);
kore_mem_free(dom->certfile);
+ dom->certfile = NULL;
kore_mem_free(dom->certkey);
+ dom->certkey = NULL;
#endif
}
diff --git a/src/http.c b/src/http.c
@@ -18,6 +18,8 @@
#include <ctype.h>
#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
#include <fcntl.h>
#include <unistd.h>
@@ -101,6 +103,21 @@ http_init(void)
"http_body_path", HTTP_BODY_PATH_MAX, prealloc);
}
+void
+http_cleanup(void)
+{
+ if (header_buf != NULL) {
+ kore_buf_free(header_buf);
+ header_buf = NULL;
+ }
+
+ kore_pool_cleanup(&http_request_pool);
+ kore_pool_cleanup(&http_header_pool);
+ kore_pool_cleanup(&http_host_pool);
+ kore_pool_cleanup(&http_path_pool);
+ kore_pool_cleanup(&http_body_path);
+}
+
int
http_request_new(struct connection *c, const char *host,
const char *method, const char *path, const char *version,
diff --git a/src/kore.c b/src/kore.c
@@ -20,6 +20,7 @@
#include <sys/socket.h>
#include <sys/resource.h>
+#include <stdio.h>
#include <netdb.h>
#include <signal.h>
@@ -417,6 +418,11 @@ kore_server_start(void)
kore_platform_event_wait(100);
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
}
+
+ kore_platform_event_cleanup();
+ kore_connection_cleanup();
+ kore_domain_cleanup();
+ net_cleanup();
}
static void
diff --git a/src/linux.c b/src/linux.c
@@ -71,6 +71,20 @@ kore_platform_event_init(void)
events = kore_calloc(event_count, sizeof(struct epoll_event));
}
+void
+kore_platform_event_cleanup(void)
+{
+ if (efd >= 0) {
+ close(efd);
+ efd = -1;
+ }
+
+ if (events != NULL) {
+ kore_mem_free(events);
+ events = NULL;
+ }
+}
+
int
kore_platform_event_wait(u_int64_t timer)
{
diff --git a/src/mem.c b/src/mem.c
@@ -50,7 +50,7 @@ kore_malloc(size_t len)
mlen = sizeof(u_int32_t) + len + sizeof(struct meminfo);
if ((ptr = calloc(1, mlen)) == NULL)
- fatal("kore_malloc(%d): %d", len, errno);
+ fatal("kore_malloc(%zd): %d", len, errno);
plen = (u_int32_t *)ptr;
*plen = len;
diff --git a/src/module.c b/src/module.c
@@ -186,9 +186,7 @@ kore_module_handler_new(const char *path, const char *domain,
if (hdlr->type == HANDLER_TYPE_DYNAMIC) {
if (regcomp(&(hdlr->rctx), hdlr->path,
REG_EXTENDED | REG_NOSUB)) {
- kore_mem_free(hdlr->func);
- kore_mem_free(hdlr->path);
- kore_mem_free(hdlr);
+ kore_module_handler_free(hdlr);
kore_debug("regcomp() on %s failed", path);
return (KORE_RESULT_ERROR);
}
@@ -198,6 +196,35 @@ kore_module_handler_new(const char *path, const char *domain,
return (KORE_RESULT_OK);
}
+void
+kore_module_handler_free(struct kore_module_handle *hdlr)
+{
+ struct kore_handler_params *param;
+
+ if (hdlr != NULL) {
+ if (hdlr->func != NULL) {
+ kore_mem_free(hdlr->func);
+ }
+ if (hdlr->path != NULL) {
+ kore_mem_free(hdlr->path);
+ }
+ if (hdlr->dom != NULL) {
+ TAILQ_REMOVE(&(hdlr->dom->handlers), hdlr, list);
+ }
+ regfree(&(hdlr->rctx));
+
+ /* Drop all validators associated with this handler */
+ while ((param=TAILQ_FIRST(&(hdlr->params))) != NULL) {
+ TAILQ_REMOVE(&(hdlr->params), param, list);
+ if (param->name != NULL) {
+ kore_mem_free(param->name);
+ }
+ kore_mem_free(param);
+ }
+ kore_mem_free(hdlr);
+ }
+}
+
struct kore_module_handle *
kore_module_handler_find(const char *domain, const char *path)
{
diff --git a/src/net.c b/src/net.c
@@ -37,6 +37,13 @@ net_init(void)
}
void
+net_cleanup(void)
+{
+ kore_debug("net_cleanup()");
+ kore_pool_cleanup(&nb_pool);
+}
+
+void
net_send_queue(struct connection *c, const void *data, u_int32_t len)
{
const u_int8_t *d;
@@ -54,7 +61,7 @@ net_send_queue(struct connection *c, const void *data, u_int32_t len)
memcpy(nb->buf + nb->b_len, d, len);
nb->b_len += len;
return;
- } else if (len > avail) {
+ } else {
memcpy(nb->buf + nb->b_len, d, avail);
nb->b_len += avail;
diff --git a/src/pool.c b/src/pool.c
@@ -22,6 +22,7 @@
#define POOL_ELEMENT_FREE 1
static void pool_region_create(struct kore_pool *, u_int32_t);
+static void pool_region_destroy(struct kore_pool *);
void
kore_pool_init(struct kore_pool *pool, const char *name,
@@ -41,6 +42,27 @@ kore_pool_init(struct kore_pool *pool, const char *name,
pool_region_create(pool, elm);
}
+void
+kore_pool_cleanup(struct kore_pool *pool)
+{
+ if (pool->inuse)
+ kore_debug("Pool %s: destroyed with %u allocs in use",
+ pool->name ? pool->name : "<unknown>",
+ pool->inuse );
+
+ pool->elms = 0;
+ pool->inuse = 0;
+ pool->elen = 0;
+ pool->slen = 0;
+
+ if (pool->name != NULL) {
+ kore_mem_free(pool->name);
+ pool->name = NULL;
+ }
+
+ pool_region_destroy(pool);
+}
+
void *
kore_pool_get(struct kore_pool *pool)
{
@@ -111,3 +133,23 @@ pool_region_create(struct kore_pool *pool, u_int32_t elms)
pool->elms += elms;
}
+
+static void
+pool_region_destroy(struct kore_pool *pool)
+{
+ struct kore_pool_region *reg;
+
+ kore_debug("pool_region_destroy(%p)", pool);
+
+ /* Take care iterating when modifying list contents */
+ while (!LIST_EMPTY(&pool->regions)) {
+ reg = LIST_FIRST(&pool->regions);
+ LIST_REMOVE(reg, list);
+ kore_mem_free(reg->start);
+ kore_mem_free(reg);
+ }
+
+ /* Freelist references into the regions memory allocations */
+ LIST_INIT(&pool->freelist);
+ pool->elms = 0;
+}
diff --git a/src/utils.c b/src/utils.c
@@ -16,6 +16,10 @@
#include <sys/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
#include <time.h>
#include <limits.h>
diff --git a/src/websocket.c b/src/websocket.c
@@ -19,6 +19,7 @@
#include <openssl/sha.h>
#include <limits.h>
+#include <string.h>
#include "kore.h"
#include "http.h"
diff --git a/src/worker.c b/src/worker.c
@@ -368,7 +368,13 @@ kore_worker_entry(struct kore_worker *kw)
#endif
}
- kore_connection_prune(KORE_CONNECTION_PRUNE_ALL);
+ kore_platform_event_cleanup();
+ kore_connection_cleanup();
+ kore_domain_cleanup();
+#if !defined(KORE_NO_HTTP)
+ http_cleanup();
+#endif
+ net_cleanup();
kore_debug("worker %d shutting down", kw->id);
exit(0);
}