@@ -30,6 +30,7 @@ SOFTWARE.
3030#include < cassert>
3131#include < iostream>
3232#include < functional>
33+ #include < mutex>
3334
3435#include " imoduleinterface.h"
3536
@@ -138,15 +139,21 @@ class ModulesIoCBase
138139
139140 void reset ()
140141 {
141- for (auto & s : m_map) {
142+ std::map<std::string_view, Service > copy;
143+ {
144+ std::lock_guard<std::mutex> lock (m_mutex);
145+ copy = m_map;
146+ m_map.clear ();
147+ }
148+
149+ for (auto & s : copy) {
142150 Service& inj = s.second ;
143151 inj.p = nullptr ;
144152
145153 for (const auto & c : inj.onChanges ) {
146154 c.second (inj.p );
147155 }
148156 }
149- m_map.clear ();
150157 }
151158
152159 ModulesIoCBase () = default ;
@@ -155,16 +162,20 @@ class ModulesIoCBase
155162
156163 void unregisterService (const InterfaceInfo& info)
157164 {
158- auto it = m_map.find (info.id );
159- if (it == m_map.end ()) {
160- return ;
161- }
165+ std::map<int , OnChangedInternal> onChanges;
166+ {
167+ std::lock_guard<std::mutex> lock (m_mutex);
168+ auto it = m_map.find (info.id );
169+ if (it == m_map.end ()) {
170+ return ;
171+ }
162172
163- Service& inj = it->second ;
164- inj.p = nullptr ;
173+ it->second .p = nullptr ;
174+ onChanges = it->second .onChanges ;
175+ }
165176
166- for (const auto & c : inj. onChanges ) {
167- c.second (inj. p );
177+ for (const auto & c : onChanges) {
178+ c.second (nullptr );
168179 }
169180 }
170181
@@ -177,33 +188,39 @@ class ModulesIoCBase
177188 return ;
178189 }
179190
180- auto foundIt = m_map.find (info.id );
181- if (foundIt != m_map.end ()) {
182- Service& inj = foundIt->second ;
183- if (inj.p ) {
184- std::cerr << module << " : double register:"
185- << info.id << " , first register in" << m_map[info.id ].sourceModule << std::endl;
186- assert (false );
191+ std::map<int , OnChangedInternal> onChanges;
192+ {
193+ std::lock_guard<std::mutex> lock (m_mutex);
194+ auto foundIt = m_map.find (info.id );
195+ if (foundIt != m_map.end ()) {
196+ Service& inj = foundIt->second ;
197+ if (inj.p ) {
198+ std::cerr << module << " : double register:"
199+ << info.id << " , first register in" << m_map[info.id ].sourceModule << std::endl;
200+ assert (false );
201+ } else {
202+ inj.sourceModule = module ;
203+ inj.p = p;
204+ onChanges = inj.onChanges ;
205+ }
187206 } else {
207+ Service inj;
188208 inj.sourceModule = module ;
189209 inj.p = p;
190- for (const auto & c : inj.onChanges ) {
191- c.second (inj.p );
192- }
210+ m_map[info.id ] = inj;
193211 }
194- } else {
195- Service inj;
196- inj.sourceModule = module ;
197- inj.p = p;
198- m_map[info.id ] = inj;
212+ }
213+
214+ for (const auto & c : onChanges) {
215+ c.second (p);
199216 }
200217 }
201218
202219 std::shared_ptr<IModuleInterface> doResolvePtrByInfo (const std::string_view& /* usageModule*/ ,
203220 const InterfaceInfo& info)
204221 {
205222 // ! TODO add statistics collection / monitoring, who resolves what
206-
223+ std::lock_guard<std::mutex> lock (m_mutex);
207224 auto it = m_map.find (info.id );
208225 if (it == m_map.end ()) {
209226 return nullptr ;
@@ -215,6 +232,7 @@ class ModulesIoCBase
215232 using OnChangedInternal = std::function<void (const std::shared_ptr<IModuleInterface>&)>;
216233 int doSubscribe (const InterfaceInfo& info, const OnChangedInternal& onChanged)
217234 {
235+ std::lock_guard<std::mutex> lock (m_mutex);
218236 auto it = m_map.find (info.id );
219237 if (it == m_map.end ()) {
220238 return -1 ;
@@ -229,6 +247,7 @@ class ModulesIoCBase
229247
230248 void doUnsubscribe (const InterfaceInfo& info, int key)
231249 {
250+ std::lock_guard<std::mutex> lock (m_mutex);
232251 auto it = m_map.find (info.id );
233252 if (it == m_map.end ()) {
234253 return ;
@@ -266,6 +285,7 @@ class ModulesIoCBase
266285 };
267286 }
268287
288+ std::mutex m_mutex;
269289 std::map<std::string_view, Service > m_map;
270290 std::shared_ptr<bool > m_alive = std::make_shared<bool >(true );
271291};
0 commit comments