diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-02-11 17:47:02 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-02-11 17:51:21 -0700 |
commit | d1ef7fab6edb3550f46f65803fe53f027cfb5dd8 (patch) | |
tree | f9970803b67751490486a1d1c84a01bebee350ba /harness/include/plugin.h | |
parent | a0f290b2e82e1331f4f932042dcdbc7d919a374f (diff) | |
download | wetterhorn-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.h | 64 |
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_ */ |