diff options
Diffstat (limited to 'harness/src')
-rw-r--r-- | harness/src/main.c | 93 | ||||
-rw-r--r-- | harness/src/plugin.c | 86 |
2 files changed, 134 insertions, 45 deletions
diff --git a/harness/src/main.c b/harness/src/main.c index 1580bd6..648473f 100644 --- a/harness/src/main.c +++ b/harness/src/main.c @@ -1,69 +1,72 @@ -#include <stdio.h> +#include "plugin.h" +#include <ctype.h> #include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> -typedef void* dllib_t; +typedef void *dllib_t; -typedef void* opqst_t; +typedef void *opqst_t; -dllib_t open_library(const char* library, int* err) -{ - dllib_t lib = dlopen(library, RTLD_LAZY); +void shx(uint8_t *state, uint32_t sz) { + uint32_t i = 0; + while (i < sz) { + for (int j = 0; j < 16; ++j) { + if (i < sz) { + printf("%02x ", (unsigned int)state[i]); + } else { + printf(" "); + } + ++i; + } - if (!lib) { - fprintf(stderr, "Error opening shared library: %s\n", dlerror()); - *err = 1; - } - *err = 0; - return lib; -} + i -= 16; + + printf(" "); -void* getsym(dllib_t handle, char* sym, int* err) -{ - void* ret = dlsym(handle, sym); - if (!ret) { - fprintf(stderr, "Unable to read symbol '%s'\n", sym); - *err |= 1; - return NULL; + for (int j = 0; j < 16; ++j) { + if (i < sz) { + if (isprint(state[i]) && !isspace(state[i])) { + printf("%c", state[i]); + } else { + printf("."); + } + } else { + printf(" "); + } + ++i; + } + printf("\n"); } - return ret; } -void use_library(int argc, char** argv, dllib_t lib, int* err) -{ - *err = 0; +void run_plugin(int argc, char **argv, plugin_t *plugin) { + fprintf(stderr, "Running plugin: %s\n", plugin->plugin_name); - opqst_t (*init)(int* argc, char*** argv) = getsym(lib, "plugin_init", err); - void (*teardown)() = getsym(lib, "plugin_teardown", err); - opqst_t (*sym)(opqst_t) = getsym(lib, "handle_thing", err); + uint32_t sz; - if (*err) { - fprintf(stderr, "Unable to find symbol call_in.\n"); - return; - } + plugin_hot_reload(argc, argv, plugin->library_handle, plugin); - opqst_t st = init(&argc, &argv); - for (int i = 0; i < 100000; ++ i) { - st = sym(st); - printf("stable_ptr: %p\n", st); - } - teardown(); + return; } -int main(int argc, char** argv) -{ +int main(int argc, char **argv) { if (!argv[0] && !argv[1]) { fprintf(stderr, "Missing argument.\n"); return 1; } - int err = 0; - dllib_t lib = open_library(argv[1], &err); - - if (err) { - return err; + plugin_t plugin; + if (read_plugin_from_file(argv[1], &plugin)) { + fprintf(stderr, "Exiting due to other failures.\n"); + return 1; } + plugin.plugin_metaload(argc, argv); + plugin.plugin_load(argc, argv); + plugin.state = plugin.plugin_cold_start(); + + run_plugin(argc, argv, &plugin); - use_library(argc, argv, lib, &err); return 0; } diff --git a/harness/src/plugin.c b/harness/src/plugin.c new file mode 100644 index 0000000..9b71c49 --- /dev/null +++ b/harness/src/plugin.c @@ -0,0 +1,86 @@ +#include "plugin.h" + +#include <ctype.h> +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +static void shx(uint8_t *state, uint32_t sz) { + uint32_t i = 0; + while (i < sz) { + for (int j = 0; j < 16; ++j) { + if (i < sz) { + printf("%02x ", (unsigned int)state[i]); + } else { + printf(" "); + } + ++i; + } + + i -= 16; + + printf(" "); + + for (int j = 0; j < 16; ++j) { + if (i < sz) { + if (isprint(state[i]) && !isspace(state[i])) { + printf("%c", state[i]); + } else { + printf("."); + } + } else { + printf(" "); + } + ++i; + } + printf("\n"); + } +} + +int read_plugin_from_file(const char *filename, plugin_t *plugin) { + dlhandle_t lib = dlopen(filename, RTLD_LAZY); + + if (!lib) { + fprintf(stderr, "Failed to open library: %s: %s\n", filename, dlerror()); + return 1; + } + + return load_plugin_from_dl(lib, plugin); +} + +int plugin_hot_reload(int argc, char **argv, dlhandle_t library, + plugin_t *plugin) { + int ec = 0; + uint32_t sz = 0; + uint8_t *marshalled_state = NULL; + + printf("Hot Reloading %s\n", plugin->plugin_name); + pthread_mutex_lock(&plugin->lock); + + printf("Marshalling state ...\n"); + marshalled_state = plugin->plugin_marshal_state(plugin->state, &sz); + + printf("Calling teardown ...\n"); + plugin->plugin_teardown(plugin->state); + + printf("State Marshalled:\n"); + shx(marshalled_state, sz); + + if (library != plugin->library_handle) { + dlclose(plugin->library_handle); + } + + if ((ec = load_plugin_from_dl(library, plugin))) { + goto fail; + } + + printf("Loading plugin ...\n"); + plugin->plugin_load(argc, argv); + printf("Hot starting plugin ...\n"); + plugin->state = plugin->plugin_hot_start(marshalled_state, sz); + +fail: + free(marshalled_state); + pthread_mutex_unlock(&plugin->lock); + return ec; +} |