From 5beac7bdd890a07cffcf9e0e03080377fde26d81 Mon Sep 17 00:00:00 2001 From: Kasper Date: Sun, 13 Apr 2025 14:14:17 +0300 Subject: [PATCH] some name storing fixes --- src/hiload.c | 82 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/src/hiload.c b/src/hiload.c index 895c6fb..5396484 100644 --- a/src/hiload.c +++ b/src/hiload.c @@ -49,7 +49,6 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, ModuleInfos *mod_infos = (ModuleInfos *)data; - // Store the module name const char *modname = info->dlpi_name; log_info("Processing: '%s'\n", info->dlpi_name); @@ -70,27 +69,30 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size, Dl_info dl_info = {0}; if (dladdr((void *)info->dlpi_addr, &dl_info)) { - sc_array_add(&mod_infos->names, strdup(dl_info.dli_fname)); + // Store the full name. Differs from dlpi_name for the executable only, + // afaik + const char *modpath = dl_info.dli_fname; + sc_array_add(&mod_infos->names, strdup(modpath)); log_debugv("dli_fname: %s\n", dl_info.dli_fname); log_debugv("dli_sname: %s\n", dl_info.dli_sname); - // Check if it's in the provided watchlist and add a watcher for (size_t i = 0; i < sc_array_size(&context.enabled_modules); i++) { + // If module is in the provided modules list if (hi_path_has_filename(modname, sc_array_at(&context.enabled_modules, i))) { - const char *filename = modname; - if (strcmp(modname, "") == 0) { - // The executable itself. Name needs to be resolved for filewatcher - filename = dl_info.dli_fname; - } - if (!HILOADRES(hi_file_watcher_add(context.filewatcher, filename, + // Replace shortform with str pointer from module info + sc_array_at(&context.enabled_modules, i) = + sc_array_last(&mod_infos->names); + + // Add filewatcher + if (!HILOADRES(hi_file_watcher_add(context.filewatcher, modpath, HI_FILE_ALL_EVENTS))) { - log_error("Failed to set filewatcher for: '%s'\n", filename); + log_error("Failed to set filewatcher for: '%s'\n", modpath); } else { - log_info("Watching file: %s\n", filename); + log_info("Watching file: %s\n", modpath); } } } @@ -142,7 +144,7 @@ static ModuleInfos *gather_module_infos(void) { return result; } -i32 get_module_index(const char *path, ModuleInfos *modinfos) { +static i32 get_module_index_by_path(const char *path, ModuleInfos *modinfos) { for (size_t i = 0; i < modinfos->count; i++) { const char *name = sc_array_at(&modinfos->names, i); @@ -154,16 +156,18 @@ i32 get_module_index(const char *path, ModuleInfos *modinfos) { } /** - * Mark modules based on file watcher events + * Mark modules based on file watcher events. + * + * Marks a module dirty if there has been any event. */ -void handle_events(struct hiFileWatcher *fw, ModuleInfos *modinfos) { +static void handle_events(struct hiFileWatcher *fw, ModuleInfos *modinfos) { hiFileEvent event = hi_file_event_pop(fw); while (event.type != HI_FILE_NONE) { log_debug("Event pop: %s – %s\n", event.pathname, hi_file_watch_type_to_str(event.type)); - i32 index = get_module_index(event.pathname, modinfos); + i32 index = get_module_index_by_path(event.pathname, modinfos); if (index < 0) { log_warn("Watched module: %s not found.\n", event.pathname); } else { @@ -173,12 +177,56 @@ void handle_events(struct hiFileWatcher *fw, ModuleInfos *modinfos) { } } -HiloadResult hi_reload() { +static i32 get_string_index(const char *needle, + const struct sc_array_str *haystack) { + i32 index = -1; + for (size_t i = 0; i < sc_array_size(haystack); i++) { + if (strcmp(needle, sc_array_at(haystack, i)) == 0) { + index = i; + break; + } + } - handle_events(context.filewatcher, context.loaded_modules); + return index; +} + +static HiloadResult reload_module(ModuleInfos *modinfos, u8 modindex) { + + modinfos->state[modindex] = HI_MODULE_STATE_CLEAN; return HILOAD_OK; } +static HiloadResult reload_dirty_modules(HiloadContext *context) { + + HiloadResult ret = HILOAD_OK; + for (u8 i = 0; i < context->loaded_modules->count; i++) { + const char *module_name = sc_array_at(&context->loaded_modules->names, i); + + // Operate on dirty modules only + if (context->loaded_modules->state[i] == HI_MODULE_STATE_DIRTY) { + + // Operate only if the module is marked as operatable + i32 module_index = + get_string_index(module_name, &context->enabled_modules); + if (module_index != -1) { + log_info("Reloading %s...\n", module_name); + + if (reload_module(context->loaded_modules, i) != HILOAD_OK) { + ret = HILOAD_FAIL; + log_error("Failed loading: %s\n", module_name); + } + } + } + } + return ret; +} + +HiloadResult hi_reload() { + + handle_events(context.filewatcher, context.loaded_modules); + reload_dirty_modules(&context); + return HILOAD_OK; +} int hi_init(unsigned n, const char **enabled_modules) {