diff options
Diffstat (limited to 'harness/src/plugin.c')
-rw-r--r-- | harness/src/plugin.c | 123 |
1 files changed, 105 insertions, 18 deletions
diff --git a/harness/src/plugin.c b/harness/src/plugin.c index 808088f..f1cc361 100644 --- a/harness/src/plugin.c +++ b/harness/src/plugin.c @@ -3,6 +3,7 @@ #include <ctype.h> #include <dlfcn.h> +#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -45,31 +46,68 @@ static void shx(uint8_t *state, uint32_t sz) int load_plugin_from_dl_(dlhandle_t dl, plugin_t *plug); +static void lock(plugin_t *plugin) +{ + pthread_mutex_lock(&plugin->lock); +}; + +static void unlock(plugin_t *plugin) +{ + pthread_mutex_unlock(&plugin->lock); +}; + +static int plugin_hot_reload_same_state_action_(plugin_t *plugin, void* ignore) +{ + return plugin_hot_reload_same_state(plugin); +} + void do_request_hot_reload(void *plugv) { plugin_t *plugin = plugv; - if (plugin->n_requested_actions < 8) { - plugin->requested_actions[plugin->n_requested_actions++].action = - plugin_hot_reload_same_state; + size_t n = plugin->n_requested_actions++; + if (n < 8) { + plugin->requested_actions[n].action = plugin_hot_reload_same_state_action_; + plugin->requested_actions[n].arg_dtor = NULL; } } -int load_plugin_from_file(int argc, char **argv, const char *filename, - plugin_t *plugin) +static int plugin_do_log(plugin_t* plugin, void* chrs) +{ + char* str = chrs; + puts(str); + return 0; +} + +void do_request_log(void *plugv, const char* str) +{ + plugin_t *plugin = plugv; + + size_t n = plugin->n_requested_actions++; + if (n < 8) { + plugin->requested_actions[n].action = plugin_do_log; + plugin->requested_actions[n].arg = strdup(str); + plugin->requested_actions[n].arg_dtor = free; + } +} + +static int load_plugin_from_file_(int argc, char **argv, const char *filename, + plugin_t *plugin) { dlhandle_t lib = dlopen(filename, RTLD_LAZY); + int ec = 0; if (!lib) { fprintf(stderr, "Failed to open library: %s: %s\n", filename, dlerror()); - return 1; + ec = 1; + goto end; } printf("Loading file.\n"); - int ec = load_plugin_from_dl_(lib, plugin); + ec = load_plugin_from_dl_(lib, plugin); if (ec) { - return ec; + goto end; } strncpy(plugin->filename, filename, sizeof(plugin->filename)); @@ -78,13 +116,43 @@ int load_plugin_from_file(int argc, char **argv, const char *filename, plugin->foreign_intf.ctx = plugin; plugin->foreign_intf.request_hot_reload = do_request_hot_reload; - return 0; + plugin->foreign_intf.do_log = do_request_log; + + plugin->plugin_load(plugin->argc, plugin->argv, &plugin->foreign_intf); +end: + return ec; +} + +int load_plugin_from_file(int argc, char **argv, const char *filename, + plugin_t *plugin) +{ + memset(plugin, 0, sizeof(*plugin)); + + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) { + perror("pthread_mutexattr_init"); + return 1; + } + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) { + perror("pthread_mutexattr_settype"); + return 1; + } + + if (pthread_mutex_init(&plugin->lock, &attr)) { + pthread_mutexattr_destroy(&attr); + perror("pthread_mutexattr_init"); + return 1; + } + pthread_mutexattr_destroy(&attr); + return load_plugin_from_file_(argc, argv, filename, plugin); } int plugin_hot_reload_same_state(plugin_t *plugin) { - return plugin_hot_reload(plugin->argc, plugin->argv, plugin->filename, - plugin); + char filename_cpy[PATH_MAX]; + strncpy(filename_cpy, plugin->filename, sizeof(filename_cpy)); + return plugin_hot_reload(plugin->argc, plugin->argv, filename_cpy, plugin); } int plugin_hot_reload(int argc, char **argv, const char *filepath, @@ -95,7 +163,7 @@ int plugin_hot_reload(int argc, char **argv, const char *filepath, uint8_t *marshalled_state = NULL; printf("Hot Reloading %s\n", plugin->plugin_name); - pthread_mutex_lock(&plugin->lock); + lock(plugin); printf("Marshalling state ...\n"); marshalled_state = plugin->plugin_marshal_state(plugin->state, &sz); @@ -107,9 +175,11 @@ int plugin_hot_reload(int argc, char **argv, const char *filepath, shx(marshalled_state, sz); printf("Unloading old library handle.\n"); - dlclose(plugin->library_handle); + if (dlclose(plugin->library_handle)) { + printf("Could not close library handle: %s\n", dlerror()); + } - if ((ec = load_plugin_from_file(argc, argv, filepath, plugin))) { + if ((ec = load_plugin_from_file_(argc, argv, filepath, plugin))) { goto fail; } @@ -120,15 +190,32 @@ int plugin_hot_reload(int argc, char **argv, const char *filepath, fail: free(marshalled_state); - pthread_mutex_unlock(&plugin->lock); + unlock(plugin); return ec; } void plugin_run_requested_actions(plugin_t *plugin) { + lock(plugin); + requested_action_t requested_actions[MAX_QUEUED_ACTIONS]; + size_t n_requested_actions = plugin->n_requested_actions; + memcpy(&requested_actions, plugin->requested_actions, + sizeof(requested_actions)); + plugin->n_requested_actions = 0; + unlock(plugin); + size_t i; - for (i = 0; i < plugin->n_requested_actions; ++i) { - plugin->requested_actions[i].action(plugin); + for (i = 0; i < n_requested_actions; ++i) { + requested_actions[i].action(plugin, requested_actions[i].arg); + if (requested_actions[i].arg_dtor) { + requested_actions[i].arg_dtor(requested_actions[i].arg); + } } - plugin->n_requested_actions = 0; +} + +void plugin_cold_start(plugin_t *plugin) +{ + lock(plugin); + plugin->state = plugin->plugin_cold_start(); + unlock(plugin); } |