aboutsummaryrefslogtreecommitdiff
path: root/harness/src/plugin.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-02-11 17:47:02 -0700
committerJosh Rahm <joshuarahm@gmail.com>2024-02-11 17:51:21 -0700
commitd1ef7fab6edb3550f46f65803fe53f027cfb5dd8 (patch)
treef9970803b67751490486a1d1c84a01bebee350ba /harness/src/plugin.c
parenta0f290b2e82e1331f4f932042dcdbc7d919a374f (diff)
downloadwetterhorn-d1ef7fab6edb3550f46f65803fe53f027cfb5dd8.tar.gz
wetterhorn-d1ef7fab6edb3550f46f65803fe53f027cfb5dd8.tar.bz2
wetterhorn-d1ef7fab6edb3550f46f65803fe53f027cfb5dd8.zip
Change up a lot of stuff.
Add more functions to the plugin interface and write some generators to generate an interface header file and the plugin's loading code.
Diffstat (limited to 'harness/src/plugin.c')
-rw-r--r--harness/src/plugin.c86
1 files changed, 86 insertions, 0 deletions
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;
+}