From c89dcbf94104d2ce92cc86ecee809a89b22dd508 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 26 Feb 2015 15:05:05 -0500 Subject: [PATCH] Ticket 48039 - Allow for pluggable malloc, calloc, etc. Description: Allow for memory functions to be pluggable. If none are set in the thrpool config, then use the stdlib memory functions. https://fedorahosted.org/389/ticket/48039/ Reviewed by: ? --- ns_event_fw_event.c | 2 +- ns_event_fw_tevent.c | 2 +- ns_thrpool.c | 123 +++++++++++++++++++++++++++++++++++++++++++++------ ns_thrpool.h | 34 ++++++++++++-- 4 files changed, 143 insertions(+), 18 deletions(-) diff --git a/ns_event_fw_event.c b/ns_event_fw_event.c index b1888bf..0d3871f 100644 --- a/ns_event_fw_event.c +++ b/ns_event_fw_event.c @@ -30,7 +30,7 @@ event_logger_cb(int severity, const char *msg) /* need to append newline */ text = PR_smprintf("%s\n",msg); ns_log(priority, text); - free(text); + ns_free(text); } static ns_job_type_t diff --git a/ns_event_fw_tevent.c b/ns_event_fw_tevent.c index 7a0024d..57d7fe8 100644 --- a/ns_event_fw_tevent.c +++ b/ns_event_fw_tevent.c @@ -42,7 +42,7 @@ tevent_logger_cb(void *context, enum tevent_debug_level level, const char *fmt, msg = PR_smprintf("%s\n",fmt); ns_log_valist(priority, msg, ap); - free(msg); + ns_free(msg); } static ns_job_type_t diff --git a/ns_thrpool.c b/ns_thrpool.c index fcfc360..08c0155 100644 --- a/ns_thrpool.c +++ b/ns_thrpool.c @@ -1,4 +1,3 @@ - #include "nspr.h" #include "pratom.h" #include "private/pprio.h" @@ -47,11 +46,17 @@ struct ns_thread_t { #define ATOMIC_VAL_IS_ZERO(val) 0 == PR_AtomicAdd((val), 0) -/* logging functions */ +/* logging function pointers */ static void (*logger)(int, const char *, va_list) = NULL; static void (*log_start)() = NULL; static void (*log_close)() = NULL; +/* memory function pointers */ +static void *(*malloc_fct)(size_t) = NULL; +static void *(*calloc_fct)(size_t, size_t) = NULL; +static void *(*realloc_fct)(void *, size_t) = NULL; +static void (*free_fct)(void *) = NULL; + /* syslog functions */ static void ns_syslog(int priority, const char *fmt, va_list varg) @@ -71,6 +76,31 @@ ns_syslog_close() closelog(); } +/* default memory functions */ +static void* +os_malloc(size_t size) +{ + return malloc(size); +} + +static void* +os_calloc(size_t count, size_t size) +{ + return calloc(count, size); +} + +static void* +os_realloc(void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +static void +os_free(void *ptr) +{ + free(ptr); +} + static void thread_stack_wait(ns_thrpool_t *tp) { @@ -658,14 +688,15 @@ setup_event_q_wakeup(ns_thrpool_t *tp) tp->event_q_wakeup_job = job; } -ns_thrpool_t * -ns_thrpool_new(struct ns_thrpool_config *tp_config) +/* + * Process the config and set the pluggable function pointers + */ +void +ns_thrpool_process_config(struct ns_thrpool_config *tp_config) { - ns_thrpool_t *tp = NULL; - ns_thread_t *thr; - PRThread *event_thr; - int ii; - + /* + * Assign our logging function pointers + */ if (tp_config->log_fct){ /* Set a logger function */ logger = tp_config->log_fct; @@ -681,12 +712,50 @@ ns_thrpool_new(struct ns_thrpool_config *tp_config) log_start = ns_syslog_start; log_close = ns_syslog_close; } - - /* Start logging */ if(log_start){ - log_start(); + /* Start logging */ + (log_start)(); } + /* + * Set the memory function pointers + */ + /* malloc */ + if (tp_config->malloc_fct){ + malloc_fct = tp_config->malloc_fct; + } else { + malloc_fct = os_malloc; + } + /* calloc */ + if (tp_config->calloc_fct){ + calloc_fct = tp_config->calloc_fct; + } else { + calloc_fct = os_calloc; + } + /* realloc */ + if (tp_config->realloc_fct){ + realloc_fct = tp_config->realloc_fct; + } else { + realloc_fct = os_realloc; + } + /* free */ + if (tp_config->free_fct){ + free_fct = tp_config->free_fct; + } else { + free_fct = os_free; + } +} + +ns_thrpool_t * +ns_thrpool_new(struct ns_thrpool_config *tp_config) +{ + ns_thrpool_t *tp = NULL; + ns_thread_t *thr; + PRThread *event_thr; + int ii; + + ns_thrpool_process_config(tp_config); + tp = ns_thrpool_alloc(); if (NULL == tp) { ns_log(LOG_ERR, "ns_thrpool_new(): failed to allocate thread pool\n"); @@ -873,7 +942,7 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp) } /* Stop logging */ if(log_close){ - log_close(); + (log_close)(); } } @@ -962,8 +1031,36 @@ ns_log(int priority, const char *fmt, ...) va_end(varg); } + void ns_log_valist(int priority, const char *fmt, va_list varg) { (logger)(priority, fmt, varg); } + +/* + * Pluggable memory functions + */ +void * +ns_malloc(size_t size) +{ + return (malloc_fct)(size); +} + +void * +ns_calloc(size_t count, size_t size) +{ + return (calloc_fct)(count, size); +} + +void * +ns_realloc(void *ptr, size_t size) +{ + return (realloc_fct)(ptr, size); +} + +void +ns_free(void *ptr) +{ + (free_fct)(ptr); +} diff --git a/ns_thrpool.h b/ns_thrpool.h index 56317bb..23f5d89 100644 --- a/ns_thrpool.h +++ b/ns_thrpool.h @@ -84,9 +84,12 @@ struct ns_thrpool_config { void (*log_fct)(int, const char *, va_list); void (*log_start_fct)(); void (*log_close_fct)(); - /* - * TODO: function pointers for malloc, realloc, and calloc - */ + + /* pluggable memory functions */ + void* (*malloc_fct)(size_t); + void* (*calloc_fct)(size_t, size_t); + void* (*realloc_fct)(void *, size_t); + void (*free_fct)(void *); }; /** @@ -105,6 +108,31 @@ void ns_log(int priority, const char *fmt, ...); */ void ns_log_valist(int priority, const char *fmt, va_list varg); +/** + * \param size - Memory allocation size + * \return - allocated memory + */ +void *ns_malloc(size_t size); + +/** + * \param count - number of items + * \param size - Memory allocation size + * \return - allocated memory + */ +void *ns_calloc(size_t count, size_t size); + +/** + * /param ptr - pointer to the memory block + * /param size - size of allocation + * /return - allocated memory + */ +void *ns_realloc(void *ptr, size_t size); + +/** + * /param ptr - pointer to memory to be freed + */ +void ns_free(void *ptr); + /* NGK TODO - document how this is supposed to be used by the job callback functions. */ void ns_job_done(struct ns_job_t *job); -- 1.9.3