diff options
author | Josh Rahm <rahm@google.com> | 2024-02-11 14:52:20 -0700 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2024-02-11 14:52:20 -0700 |
commit | a0f290b2e82e1331f4f932042dcdbc7d919a374f (patch) | |
tree | 66e8c90990a913fd1fc7ee791bbcda71656f5775 | |
parent | a4a3ea6b0f14cbd3f19bedf26a40c6ef45868a15 (diff) | |
download | wetterhorn-a0f290b2e82e1331f4f932042dcdbc7d919a374f.tar.gz wetterhorn-a0f290b2e82e1331f4f932042dcdbc7d919a374f.tar.bz2 wetterhorn-a0f290b2e82e1331f4f932042dcdbc7d919a374f.zip |
Start making some more changes to harness and add plugin interface.
-rw-r--r-- | harness/include/plugin.h | 101 | ||||
-rw-r--r-- | src/harness_adapter.c | 2 |
2 files changed, 103 insertions, 0 deletions
diff --git a/harness/include/plugin.h b/harness/include/plugin.h new file mode 100644 index 0000000..70ca198 --- /dev/null +++ b/harness/include/plugin.h @@ -0,0 +1,101 @@ +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include <dlfcn.h> +#include <stdint.h> +#include <pthread.h> + +#define PRIVATE(a) a + +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; + +/* + * Structure for the plugin. + */ +typedef struct PLUGIN { + /* Opaque state of this plugin. The state is usually some kind of pointer to + * the plugin state, but all the harness knows is the opaque state is a + * pointer-sized piece of data. + * + * This opaque state is used in a linear pattern where the handlers take the + * opaque state, maybe operate on it, and return a new opaque state, which is + * then passed to the next handler, etc. It is on the plugin to properly + * manager the memory for this state and to destroy it upon teardown. + * + * 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); + + /* 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); + + /* The handle to the shared library. */ + PRIVATE(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); + + /** 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); + + /* Start the plugin with the marshalled state from the previous plugin. + * + * This should return the opaque state from the mashalled_state. + * + * This function should not fail if the state cannot be demarshalled, rather a + * default state should be returned. This is because changing the plugin and + * 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); + + /* + * Starts the plugin without a marshalled state. Happens during the first boot + * when there is not state. + */ + opqst_t (*plugin_cold_start)(); + + /* + * Marshals the state to a bytestring. The returned pointer should be malloc'd + * on the heap. The harness takes ownership of the malloc'd pointer. + * + * 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); + + /* + * 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; + +} 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); + +/* Like the above, but load the library from the given file. */ +int load_plugin_from_file(plugin_t* out, const char* dlfilename); + +#endif /* _PLUGIN_H_ */ diff --git a/src/harness_adapter.c b/src/harness_adapter.c index 4d751c0..dbae57a 100644 --- a/src/harness_adapter.c +++ b/src/harness_adapter.c @@ -15,3 +15,5 @@ void plugin_teardown() { hs_exit(); } + +const char* plugin_name = "Wetterhorn"; |