aboutsummaryrefslogtreecommitdiff
path: root/harness/include/plugin.h
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/include/plugin.h
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/include/plugin.h')
-rw-r--r--harness/include/plugin.h64
1 files changed, 38 insertions, 26 deletions
diff --git a/harness/include/plugin.h b/harness/include/plugin.h
index 70ca198..db15401 100644
--- a/harness/include/plugin.h
+++ b/harness/include/plugin.h
@@ -2,16 +2,20 @@
#define _PLUGIN_H_
#include <dlfcn.h>
-#include <stdint.h>
#include <pthread.h>
+#include <stdint.h>
-#define PRIVATE(a) a
+/*
+ * Marker macro to define what functions should be exported. This generates the
+ * interface which the plugin needs to implement.
+ */
+#define EXPORT(a) a
-typedef void* dlhandle_t;
+typedef void *dlhandle_t;
/* Opaque state for a plugin. Not to be touched by the harness (not that it
* really can be.) */
-typedef void* opqst_t;
+typedef void *opqst_t;
/*
* Structure for the plugin.
@@ -28,25 +32,34 @@ typedef struct PLUGIN {
*
* It's guaranteed that this state is used linearly, meaning the harness gives
* up all ownership to it once passed into a handler. */
- PRIVATE(opqst_t state);
+ opqst_t state;
/* This plugin's lock. This avoids potential issues with multiple threads
* trying to change the opaque state at once which can lead to undesireable
* outcomes. */
- PRIVATE(pthread_mutex_t lock);
+ pthread_mutex_t lock;
/* The handle to the shared library. */
- PRIVATE(dlhandle_t library_handle);
+ dlhandle_t library_handle;
/* Pointer to the plugin name. This is in the shared library and a
* null-terminated string. If the library does not have a plugin name, this
* will be NULL. */
- PRIVATE(const char* plugin_name);
+ const char *plugin_name;
+
+ /**
+ * This is the first thing called on the plugin when loading it. This is
+ * different from plugin_load in that it will not be called on a hot-reload.
+ *
+ * This is used as a hack to get around GHC's limitation where it can't
+ * start up the RTS once it has been shutdown.
+ */
+ EXPORT(void (*plugin_metaload)(int argc, char** argv));
/** Intializes the plugin with the given argc/argv. This is the first thing
* called on the plugin and is called immediately after the library is loaded.
*/
- void (*plugin_load)(int argc, char** argv);
+ EXPORT(void (*plugin_load)(int argc, char **argv));
/* Start the plugin with the marshalled state from the previous plugin.
*
@@ -57,13 +70,13 @@ typedef struct PLUGIN {
* hot-reloading can produce incompatibilities between the old state and the
* new state, and this should not cause a failure.
*/
- opqst_t (*plugin_hot_start)(uint8_t* mashalled_state, uint32_t n);
+ EXPORT(opqst_t (*plugin_hot_start)(uint8_t *mashalled_state, uint32_t n));
/*
* Starts the plugin without a marshalled state. Happens during the first boot
* when there is not state.
*/
- opqst_t (*plugin_cold_start)();
+ EXPORT(opqst_t (*plugin_cold_start)());
/*
* Marshals the state to a bytestring. The returned pointer should be malloc'd
@@ -72,30 +85,29 @@ typedef struct PLUGIN {
* This is usually called in preparation for a teardown followed by a
* hot-start.
*/
- uint8_t* (*plugin_marshal_state)(opqst_t st, uint32_t* szout);
+ EXPORT(uint8_t *(*plugin_marshal_state)(opqst_t st, uint32_t *szout));
/*
* Teardown the plugin in preperation for the library's imminent unloading.
*/
- void (*plugin_teardown)(opqst_t);
-
- /* This anonymous structure contains event handlers. It is wrapped in this
- * structure to make it distinct from the management functions above.
- *
- * The handlers are all optional and if any of them are NULL, the opaque state
- * remains untouched.
- */
- struct {
- /* Right now, empty */
- } handlers;
+ EXPORT(void (*plugin_teardown)(opqst_t));
} plugin_t;
/** Loads a plugin from the dynamic library handle. Returns a non-zero error
* code on error. */
-int load_plugin_from_dlhandle(plugin_t* out, dlhandle_t library);
+int load_plugin_from_dl(dlhandle_t library, plugin_t *out);
+
+/* Reloads the plugin. This tears down the existing plugin, marshals the state
+ * for it and reloads it.
+ *
+ * This function will call dlclose on the plugin's library handle if it is not
+ * the same as 'library'.
+ */
+int plugin_hot_reload(int argc, char **argv, dlhandle_t library,
+ plugin_t *plugin);
-/* Like the above, but load the library from the given file. */
-int load_plugin_from_file(plugin_t* out, const char* dlfilename);
+/* Reads a plugin from a filename. */
+int read_plugin_from_file(const char *filename, plugin_t *plugin);
#endif /* _PLUGIN_H_ */