aboutsummaryrefslogtreecommitdiff
path: root/harness/src
diff options
context:
space:
mode:
Diffstat (limited to 'harness/src')
-rw-r--r--harness/src/main.c93
-rw-r--r--harness/src/plugin.c86
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;
+}