aboutsummaryrefslogtreecommitdiff
path: root/harness/src/plugin.c
diff options
context:
space:
mode:
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);
}