feat(module.c, stk.c): expose dependency functions and integrate into init and poll
- Make stk_validate_dependencies and stk_topo_sort non static - Add extern declarations in stk.c - Run stk_validate_dependencies after module loads in stk_init - Validation failure is fatal; unload all modules and return error code - Run stk_topo_sort after validation, sort failure is logged but not fatal - Add validate_deps label in stk_poll so all load/unload paths run validation - Add dep error codes to stk_error_string
This commit is contained in:
+2
-2
@@ -156,7 +156,7 @@ int is_mod_loaded(const char *module_name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char stk_validate_dependencies(size_t count)
|
unsigned char stk_validate_dependencies(size_t count)
|
||||||
{
|
{
|
||||||
size_t i, d;
|
size_t i, d;
|
||||||
int found;
|
int found;
|
||||||
@@ -183,7 +183,7 @@ static unsigned char stk_validate_dependencies(size_t count)
|
|||||||
return STK_MOD_INIT_SUCCESS;
|
return STK_MOD_INIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char stk_topo_sort(size_t count, size_t *order)
|
unsigned char stk_topo_sort(size_t count, size_t *order)
|
||||||
{
|
{
|
||||||
size_t *in_degree = NULL;
|
size_t *in_degree = NULL;
|
||||||
size_t *queue = NULL;
|
size_t *queue = NULL;
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ unsigned char stk_module_init_memory(size_t capacity);
|
|||||||
unsigned char stk_module_realloc_memory(size_t new_capacity);
|
unsigned char stk_module_realloc_memory(size_t new_capacity);
|
||||||
void stk_module_unload(size_t index);
|
void stk_module_unload(size_t index);
|
||||||
void stk_module_unload_all(void);
|
void stk_module_unload_all(void);
|
||||||
|
unsigned char stk_validate_dependencies(size_t count);
|
||||||
|
unsigned char stk_topo_sort(size_t count, size_t *order);
|
||||||
|
|
||||||
static void build_path(char *dest, size_t dest_size, const char *dir,
|
static void build_path(char *dest, size_t dest_size, const char *dir,
|
||||||
const char *file)
|
const char *file)
|
||||||
@@ -77,6 +79,12 @@ static const char *stk_error_string(int error_code)
|
|||||||
return "init failure";
|
return "init failure";
|
||||||
case STK_MOD_REALLOC_FAILURE:
|
case STK_MOD_REALLOC_FAILURE:
|
||||||
return "memory reallocation failed";
|
return "memory reallocation failed";
|
||||||
|
case STK_MOD_DEP_NOT_FOUND_ERROR:
|
||||||
|
return "dependency not found";
|
||||||
|
case STK_MOD_DEP_VERSION_MISMATCH_ERROR:
|
||||||
|
return "dependency version mismatch";
|
||||||
|
case STK_MOD_DEP_CIRCULAR_ERROR:
|
||||||
|
return "circular dependency detected";
|
||||||
default:
|
default:
|
||||||
return "unknown error";
|
return "unknown error";
|
||||||
}
|
}
|
||||||
@@ -89,6 +97,8 @@ unsigned char stk_init(void)
|
|||||||
char full_path[STK_PATH_MAX_OS];
|
char full_path[STK_PATH_MAX_OS];
|
||||||
char tmp_path[STK_PATH_MAX_OS];
|
char tmp_path[STK_PATH_MAX_OS];
|
||||||
int load_result;
|
int load_result;
|
||||||
|
unsigned char dep_result;
|
||||||
|
size_t *order = NULL;
|
||||||
|
|
||||||
platform_mkdir(stk_mod_dir);
|
platform_mkdir(stk_mod_dir);
|
||||||
build_path(stk_tmp_dir, sizeof(stk_tmp_dir), stk_mod_dir, stk_tmp_name);
|
build_path(stk_tmp_dir, sizeof(stk_tmp_dir), stk_mod_dir, stk_tmp_name);
|
||||||
@@ -140,12 +150,31 @@ unsigned char stk_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (successful_loads < file_count) {
|
if (successful_loads < file_count)
|
||||||
stk_module_realloc_memory(successful_loads);
|
stk_module_realloc_memory(successful_loads);
|
||||||
}
|
|
||||||
|
|
||||||
free(files);
|
free(files);
|
||||||
|
|
||||||
|
if (module_count == 0)
|
||||||
|
goto scanned;
|
||||||
|
|
||||||
|
dep_result = stk_validate_dependencies(module_count);
|
||||||
|
if (dep_result != STK_MOD_INIT_SUCCESS) {
|
||||||
|
stk_log(STK_LOG_ERROR, "Dependency validation failed: %s",
|
||||||
|
stk_error_string(dep_result));
|
||||||
|
stk_module_unload_all();
|
||||||
|
return dep_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
order = malloc(module_count * sizeof(size_t));
|
||||||
|
if (order) {
|
||||||
|
dep_result = stk_topo_sort(module_count, order);
|
||||||
|
if (dep_result != STK_MOD_INIT_SUCCESS)
|
||||||
|
stk_log(STK_LOG_ERROR, "Dependency sort failed: %s",
|
||||||
|
stk_error_string(dep_result));
|
||||||
|
free(order);
|
||||||
|
}
|
||||||
|
|
||||||
scanned:
|
scanned:
|
||||||
watch_handle = platform_directory_watch_start(stk_mod_dir);
|
watch_handle = platform_directory_watch_start(stk_mod_dir);
|
||||||
if (!watch_handle) {
|
if (!watch_handle) {
|
||||||
@@ -199,6 +228,8 @@ size_t stk_poll(void)
|
|||||||
int load_result;
|
int load_result;
|
||||||
size_t successful_appends = 0;
|
size_t successful_appends = 0;
|
||||||
char (*module_ids)[STK_MOD_ID_BUFFER] = NULL;
|
char (*module_ids)[STK_MOD_ID_BUFFER] = NULL;
|
||||||
|
unsigned char dep_result;
|
||||||
|
size_t *order = NULL;
|
||||||
|
|
||||||
if (module_count > 0) {
|
if (module_count > 0) {
|
||||||
module_ids = malloc(module_count * sizeof(*module_ids));
|
module_ids = malloc(module_count * sizeof(*module_ids));
|
||||||
@@ -276,9 +307,8 @@ size_t stk_poll(void)
|
|||||||
handle_grow:
|
handle_grow:
|
||||||
remaining_loads = load_count - unload_count;
|
remaining_loads = load_count - unload_count;
|
||||||
new_capacity = module_count + remaining_loads;
|
new_capacity = module_count + remaining_loads;
|
||||||
if (stk_module_realloc_memory(new_capacity) != STK_MOD_INIT_SUCCESS) {
|
if (stk_module_realloc_memory(new_capacity) != STK_MOD_INIT_SUCCESS)
|
||||||
goto free_poll;
|
goto free_poll;
|
||||||
}
|
|
||||||
|
|
||||||
begin_operations:
|
begin_operations:
|
||||||
for (i = 0; i < unload_count; ++i)
|
for (i = 0; i < unload_count; ++i)
|
||||||
@@ -303,12 +333,11 @@ begin_operations:
|
|||||||
}
|
}
|
||||||
|
|
||||||
load_result = stk_module_load(tmp_path, mod_index);
|
load_result = stk_module_load(tmp_path, mod_index);
|
||||||
if (load_result != STK_MOD_INIT_SUCCESS) {
|
if (load_result != STK_MOD_INIT_SUCCESS)
|
||||||
stk_log(STK_LOG_ERROR, "Failed to reload module %s: %s",
|
stk_log(STK_LOG_ERROR, "Failed to reload module %s: %s",
|
||||||
file_list[file_index],
|
file_list[file_index],
|
||||||
stk_error_string(load_result));
|
stk_error_string(load_result));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
holes_to_fill = (load_count < unload_count) ? load_count : unload_count;
|
holes_to_fill = (load_count < unload_count) ? load_count : unload_count;
|
||||||
for (i = 0; i < holes_to_fill; ++i) {
|
for (i = 0; i < holes_to_fill; ++i) {
|
||||||
@@ -328,12 +357,11 @@ begin_operations:
|
|||||||
}
|
}
|
||||||
|
|
||||||
load_result = stk_module_load(tmp_path, target_index);
|
load_result = stk_module_load(tmp_path, target_index);
|
||||||
if (load_result != STK_MOD_INIT_SUCCESS) {
|
if (load_result != STK_MOD_INIT_SUCCESS)
|
||||||
stk_log(STK_LOG_ERROR, "Failed to load module %s: %s",
|
stk_log(STK_LOG_ERROR, "Failed to load module %s: %s",
|
||||||
file_list[file_index],
|
file_list[file_index],
|
||||||
stk_error_string(load_result));
|
stk_error_string(load_result));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (load_count > unload_count)
|
if (load_count > unload_count)
|
||||||
goto append_modules;
|
goto append_modules;
|
||||||
@@ -341,7 +369,7 @@ begin_operations:
|
|||||||
if (unload_count > load_count)
|
if (unload_count > load_count)
|
||||||
goto trim_arrays;
|
goto trim_arrays;
|
||||||
|
|
||||||
goto free_poll;
|
goto validate_deps;
|
||||||
|
|
||||||
append_modules:
|
append_modules:
|
||||||
for (; i < load_count; ++i) {
|
for (; i < load_count; ++i) {
|
||||||
@@ -372,11 +400,10 @@ append_modules:
|
|||||||
|
|
||||||
module_count += successful_appends;
|
module_count += successful_appends;
|
||||||
|
|
||||||
if (successful_appends < (load_count - holes_to_fill)) {
|
if (successful_appends < (load_count - holes_to_fill))
|
||||||
stk_module_realloc_memory(module_count);
|
stk_module_realloc_memory(module_count);
|
||||||
}
|
|
||||||
|
|
||||||
goto free_poll;
|
goto validate_deps;
|
||||||
|
|
||||||
trim_arrays:
|
trim_arrays:
|
||||||
write_pos = unloaded_mod_indices[holes_to_fill];
|
write_pos = unloaded_mod_indices[holes_to_fill];
|
||||||
@@ -395,6 +422,26 @@ trim_arrays:
|
|||||||
module_count = write_pos;
|
module_count = write_pos;
|
||||||
stk_module_realloc_memory(module_count);
|
stk_module_realloc_memory(module_count);
|
||||||
|
|
||||||
|
validate_deps:
|
||||||
|
if (module_count == 0)
|
||||||
|
goto free_poll;
|
||||||
|
|
||||||
|
dep_result = stk_validate_dependencies(module_count);
|
||||||
|
if (dep_result != STK_MOD_INIT_SUCCESS) {
|
||||||
|
stk_log(STK_LOG_ERROR, "Dependency validation failed: %s",
|
||||||
|
stk_error_string(dep_result));
|
||||||
|
goto free_poll;
|
||||||
|
}
|
||||||
|
|
||||||
|
order = malloc(module_count * sizeof(size_t));
|
||||||
|
if (order) {
|
||||||
|
dep_result = stk_topo_sort(module_count, order);
|
||||||
|
if (dep_result != STK_MOD_INIT_SUCCESS)
|
||||||
|
stk_log(STK_LOG_ERROR, "Dependency sort failed: %s",
|
||||||
|
stk_error_string(dep_result));
|
||||||
|
free(order);
|
||||||
|
}
|
||||||
|
|
||||||
free_poll:
|
free_poll:
|
||||||
free(reloaded_mod_indices);
|
free(reloaded_mod_indices);
|
||||||
free(reloaded_mod_file_indices);
|
free(reloaded_mod_file_indices);
|
||||||
|
|||||||
Reference in New Issue
Block a user