#include "plugin.h" #include #include #include #include static void shx(uint8_t *state, uint32_t sz) { uint32_t i = 0; while (i < sz) { for (int j = 0; j < 16; ++j) { if (i < sz) { printf("%02x ", (unsigned int)state[i]); } else { printf(" "); } ++i; } i -= 16; printf(" "); for (int j = 0; j < 16; ++j) { if (i < sz) { if (isprint(state[i]) && !isspace(state[i])) { printf("%c", state[i]); } else { printf("."); } } else { printf(" "); } ++i; } printf("\n"); } } int load_plugin_from_file(const char *filename, plugin_t *plugin) { dlhandle_t lib = dlopen(filename, RTLD_LAZY); if (!lib) { fprintf(stderr, "Failed to open library: %s: %s\n", filename, dlerror()); return 1; } printf("Loading file.\n"); return load_plugin_from_dl(lib, plugin); } int plugin_hot_reload(int argc, char **argv, const char *filepath, plugin_t *plugin) { int ec = 0; uint32_t sz = 0; uint8_t *marshalled_state = NULL; printf("Hot Reloading %s\n", plugin->plugin_name); pthread_mutex_lock(&plugin->lock); printf("Marshalling state ...\n"); marshalled_state = plugin->plugin_marshal_state(plugin->state, &sz); printf("Calling teardown ...\n"); plugin->plugin_teardown(plugin->state); printf("State Marshalled:\n"); shx(marshalled_state, sz); printf("Unloading old library handle.\n"); dlclose(plugin->library_handle); if ((ec = load_plugin_from_file(filepath, plugin))) { goto fail; } printf("Loading plugin ...\n"); plugin->plugin_load(argc, argv); printf("Hot starting plugin ...\n"); plugin->state = plugin->plugin_hot_start(marshalled_state, sz); fail: free(marshalled_state); pthread_mutex_unlock(&plugin->lock); return ec; }