aboutsummaryrefslogtreecommitdiff
path: root/harness/src/plugin.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-02-14 10:39:01 -0700
committerJosh Rahm <joshuarahm@gmail.com>2024-02-14 10:39:01 -0700
commit020bc92281ae584dc97aa30e1a1ad2a5373335fd (patch)
tree1eb1036d55e116fc055feee6e9502b8445d89872 /harness/src/plugin.c
parent10a5272eaca6407982b3707027ea8704f3484377 (diff)
downloadmontis-020bc92281ae584dc97aa30e1a1ad2a5373335fd.tar.gz
montis-020bc92281ae584dc97aa30e1a1ad2a5373335fd.tar.bz2
montis-020bc92281ae584dc97aa30e1a1ad2a5373335fd.zip
Framework for plugin to call into harness.
This is done by passing an interface to the plugin from the harness. The plugin can then request the harness do some things (such as reload), and the harness will do that.
Diffstat (limited to 'harness/src/plugin.c')
-rw-r--r--harness/src/plugin.c123
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);
}