From b2a74fd651a0be8cb2866168c691e28eb8fc7ca0 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Thu, 12 Jan 2023 10:28:24 -0800 Subject: [PATCH] added cleanup/unload api (#27) --- ecsactsi_wasm.cc | 40 +++++++++++++++++++++++++++++++++- ecsactsi_wasm.h | 18 +++++++++++++++ wasm_ecsact_system_execution.h | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/ecsactsi_wasm.cc b/ecsactsi_wasm.cc index b97f6bf..9a6d4d5 100644 --- a/ecsactsi_wasm.cc +++ b/ecsactsi_wasm.cc @@ -279,6 +279,20 @@ wasm_engine_t* engine() { return engine; } +void unload_system_module( + ecsact_system_like_id sys_id, + ecsact_internal_wasm_system_module_info& info +) { + ecsact_set_system_execution_impl(sys_id, nullptr); + wasm_module_delete(info.system_module); + wasm_instance_delete(info.instance); + wasm_func_delete(info.system_impl_func); + wasm_memory_delete(info.system_impl_memory); + wasm_store_delete(info.store); + + info = {}; +} + void ecsactsi_wasm_system_impl(ecsact_system_execution_context* ctx) { auto lk = std::shared_lock(modules_mutex); auto system_id = ecsact_system_execution_context_id(ctx); @@ -459,7 +473,7 @@ ecsactsi_wasm_error ecsactsi_wasm_load( std::unique_lock lk(modules_mutex); for(auto&& [system_id, pending_info] : pending_modules) { if(modules.contains(system_id)) { - // TODO(zaucy): Cleanup existing module info + unload_system_module(system_id, modules.at(system_id)); } modules[system_id] = std::move(pending_info); @@ -503,3 +517,27 @@ void ecsactsi_wasm_set_trap_handler(ecsactsi_wasm_trap_handler handler) { std::shared_lock lk(modules_mutex); trap_handler = handler; } + +void ecsactsi_wasm_unload( + int systems_count, + ecsact_system_like_id* system_ids +) { + std::unique_lock lk(modules_mutex); + for(int i = 0; systems_count > i; ++i) { + auto system_id = system_ids[i]; + auto module_itr = modules.find(system_id); + if(module_itr != modules.end()) { + unload_system_module(system_id, module_itr->second); + modules.erase(module_itr); + } + } +} + +void ecsactsi_wasm_reset() { + std::unique_lock lk(modules_mutex); + for(auto&& [sys_id, m] : modules) { + unload_system_module(sys_id, m); + } + modules.clear(); + trap_handler = nullptr; +} diff --git a/ecsactsi_wasm.h b/ecsactsi_wasm.h index 874ccf9..72f068c 100644 --- a/ecsactsi_wasm.h +++ b/ecsactsi_wasm.h @@ -124,6 +124,24 @@ ECSACTSI_WASM_API_FN(ecsactsi_wasm_error, ecsactsi_wasm_load) const char** wasm_exports ); +/** + * Unload 1 or more systems. If a system is not already loaded this is a noop. + * @param systems_count number of systems impls to unload + * @param system_ids array of system IDs to unload. Sequential list length of + * @p systems_count. + */ +ECSACTSI_WASM_API_FN(void, ecsactsi_wasm_unload) +( // + int systems_count, + ecsact_system_like_id* system_ids +); + +/** + * Reset state. Effectively called `ecsactsi_wasm_unload` for each system + * implementation and clears the trap handler. + */ +ECSACTSI_WASM_API_FN(void, ecsactsi_wasm_reset)(); + /** * @param system_id System ID associated with the impl that triggered the trap * @param trap_message The trap message contents. Null-terminated string. diff --git a/wasm_ecsact_system_execution.h b/wasm_ecsact_system_execution.h index f9f92ac..3628c22 100644 --- a/wasm_ecsact_system_execution.h +++ b/wasm_ecsact_system_execution.h @@ -17,7 +17,7 @@ struct ecsact_internal_execution_context_linked_list { struct ecsact_internal_wasm_system_module_info { wasm_module_t* system_module; wasm_instance_t* instance; - const wasm_func_t* system_impl_func; + wasm_func_t* system_impl_func; wasm_memory_t* system_impl_memory; wasm_store_t* store; const ecsact_system_execution_context* parent;