/src/WasmEdge/include/runtime/storemgr.h
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: 2019-2024 Second State INC |
3 | | |
4 | | //===-- wasmedge/runtime/storemgr.h - Store Manager definition ------------===// |
5 | | // |
6 | | // Part of the WasmEdge Project. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// |
10 | | /// \file |
11 | | /// This file contains the definition of Store Manager. |
12 | | /// |
13 | | //===----------------------------------------------------------------------===// |
14 | | #pragma once |
15 | | |
16 | | #include "runtime/instance/component.h" |
17 | | #include "runtime/instance/module.h" |
18 | | |
19 | | #include <mutex> |
20 | | #include <shared_mutex> |
21 | | #include <vector> |
22 | | |
23 | | namespace WasmEdge { |
24 | | |
25 | | namespace Executor { |
26 | | class Executor; |
27 | | } |
28 | | |
29 | | namespace Runtime { |
30 | | |
31 | | class StoreManager { |
32 | | public: |
33 | 0 | StoreManager() = default; |
34 | 0 | ~StoreManager() { |
35 | | // When destroying this store manager, unlink all the registered module |
36 | | // instances. |
37 | 0 | reset(); |
38 | 0 | } |
39 | | |
40 | | /// Get the length of the list of registered modules. |
41 | 0 | uint32_t getModuleListSize() const noexcept { |
42 | 0 | std::shared_lock Lock(Mutex); |
43 | 0 | return static_cast<uint32_t>(NamedMod.size()); |
44 | 0 | } |
45 | | |
46 | | /// Get list of registered modules. |
47 | 0 | template <typename CallbackT> auto getModuleList(CallbackT &&CallBack) const { |
48 | 0 | std::shared_lock Lock(Mutex); |
49 | 0 | return std::forward<CallbackT>(CallBack)(NamedMod); |
50 | 0 | } Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::StoreManager::getModuleList<WasmEdge_StoreListModule::$_0>(WasmEdge_StoreListModule::$_0&&) const Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::StoreManager::getModuleList<WasmEdge_VMListRegisteredModule::$_0>(WasmEdge_VMListRegisteredModule::$_0&&) const |
51 | | |
52 | | /// Find module by name. |
53 | 0 | const Instance::ModuleInstance *findModule(std::string_view Name) const { |
54 | 0 | std::shared_lock Lock(Mutex); |
55 | 0 | if (auto Iter = SoftNamedMod.find(Name); |
56 | 0 | likely(Iter != SoftNamedMod.cend())) { |
57 | 0 | return Iter->second; |
58 | 0 | } |
59 | 0 | if (auto Iter = NamedMod.find(Name); likely(Iter != NamedMod.cend())) { |
60 | 0 | return Iter->second; |
61 | 0 | } |
62 | 0 | return nullptr; |
63 | 0 | } |
64 | | const Instance::ComponentInstance * |
65 | 0 | findComponent(std::string_view Name) const { |
66 | 0 | std::shared_lock Lock(Mutex); |
67 | 0 | if (auto Iter = NamedComp.find(Name); likely(Iter != NamedComp.cend())) { |
68 | 0 | return Iter->second; |
69 | 0 | } |
70 | 0 | return nullptr; |
71 | 0 | } |
72 | | |
73 | | /// Reset this store manager and unlink all the registered module instances. |
74 | 0 | void reset() noexcept { |
75 | 0 | std::shared_lock Lock(Mutex); |
76 | 0 | for (auto &&Pair : NamedMod) { |
77 | 0 | (const_cast<Instance::ModuleInstance *>(Pair.second))->unlinkStore(this); |
78 | 0 | } |
79 | 0 | NamedMod.clear(); |
80 | 0 | } |
81 | | |
82 | | /// Register named module into this store. |
83 | 0 | Expect<void> registerModule(const Instance::ModuleInstance *ModInst) { |
84 | 0 | std::unique_lock Lock(Mutex); |
85 | 0 | auto Iter = NamedMod.find(ModInst->getModuleName()); |
86 | 0 | if (likely(Iter != NamedMod.cend())) { |
87 | 0 | return Unexpect(ErrCode::Value::ModuleNameConflict); |
88 | 0 | } |
89 | 0 | NamedMod.emplace(ModInst->getModuleName(), ModInst); |
90 | | // Link the module instance to this store manager. |
91 | 0 | (const_cast<Instance::ModuleInstance *>(ModInst)) |
92 | 0 | ->linkStore(this, [](StoreManager *Store, |
93 | 0 | const Instance::ModuleInstance *Inst) { |
94 | | // The unlink callback. |
95 | 0 | std::unique_lock CallbackLock(Store->Mutex); |
96 | 0 | (Store->NamedMod).erase(std::string(Inst->getModuleName())); |
97 | 0 | }); |
98 | 0 | return {}; |
99 | 0 | } |
100 | | |
101 | | void addNamedModule(std::string_view Name, |
102 | 0 | const Instance::ModuleInstance *Inst) { |
103 | 0 | std::unique_lock Lock(Mutex); |
104 | 0 | SoftNamedMod.emplace(Name, Inst); |
105 | 0 | } |
106 | | |
107 | | Expect<void> registerComponent(std::string_view Name, |
108 | 0 | const Instance::ComponentInstance *Inst) { |
109 | 0 | std::unique_lock Lock(Mutex); |
110 | 0 | auto Iter = NamedComp.find(Name); |
111 | 0 | if (likely(Iter != NamedComp.cend())) { |
112 | 0 | return Unexpect(ErrCode::Value::ModuleNameConflict); |
113 | 0 | } |
114 | 0 | NamedComp.emplace(Name, Inst); |
115 | 0 | return {}; |
116 | 0 | } |
117 | 0 | Expect<void> registerComponent(const Instance::ComponentInstance *Inst) { |
118 | 0 | return registerComponent(Inst->getComponentName(), Inst); |
119 | 0 | } |
120 | | |
121 | | private: |
122 | | /// \name Mutex for thread-safe. |
123 | | mutable std::shared_mutex Mutex; |
124 | | |
125 | | friend class Executor::Executor; |
126 | | |
127 | | /// Collect the instantiation failed module. |
128 | 0 | void recycleModule(std::unique_ptr<Instance::ModuleInstance> &&Mod) { |
129 | 0 | FailedMod = std::move(Mod); |
130 | 0 | } |
131 | | |
132 | | /// \name Module name mapping. |
133 | | std::map<std::string, const Instance::ModuleInstance *, std::less<>> NamedMod; |
134 | | /// \name Soft module are those temporary added by component linking process |
135 | | std::map<std::string, const Instance::ModuleInstance *, std::less<>> |
136 | | SoftNamedMod; |
137 | | std::map<std::string, const Instance::ComponentInstance *, std::less<>> |
138 | | NamedComp; |
139 | | |
140 | | /// \name Last instantiation failed module. |
141 | | /// According to the current spec, the instances should be able to be |
142 | | /// referenced even if instantiation failed. Therefore store the failed module |
143 | | /// instance here to keep the instances. |
144 | | /// FIXME: Is this necessary to be a vector? |
145 | | std::unique_ptr<Instance::ModuleInstance> FailedMod; |
146 | | }; |
147 | | |
148 | | } // namespace Runtime |
149 | | } // namespace WasmEdge |