11#include " RuntimeLifecycleMonitor.h"
22
3+ #include < mutex>
34#include < unordered_map>
45#include < unordered_set>
56#include < utility>
@@ -9,25 +10,43 @@ namespace RNJsi {
910static std::unordered_map<jsi::Runtime *,
1011 std::unordered_set<RuntimeLifecycleListener *>>
1112 listeners;
13+ static std::mutex listenersMutex;
1214
1315struct RuntimeLifecycleMonitorObject : public jsi ::HostObject {
1416 jsi::Runtime *_rt;
1517 explicit RuntimeLifecycleMonitorObject (jsi::Runtime *rt) : _rt(rt) {}
1618 ~RuntimeLifecycleMonitorObject () {
17- auto listenersSet = listeners.find (_rt);
18- if (listenersSet != listeners.end ()) {
19- for (auto listener : listenersSet->second ) {
20- listener->onRuntimeDestroyed (_rt);
19+ std::unordered_set<RuntimeLifecycleListener *> listenersCopy;
20+ {
21+ std::lock_guard<std::mutex> lock (listenersMutex);
22+ auto listenersSet = listeners.find (_rt);
23+ if (listenersSet != listeners.end ()) {
24+ listenersCopy = listenersSet->second ;
25+ listeners.erase (listenersSet);
2126 }
22- listeners.erase (listenersSet);
27+ }
28+ for (auto listener : listenersCopy) {
29+ listener->onRuntimeDestroyed (_rt);
2330 }
2431 }
2532};
2633
2734void RuntimeLifecycleMonitor::addListener (jsi::Runtime &rt,
2835 RuntimeLifecycleListener *listener) {
29- auto listenersSet = listeners.find (&rt);
30- if (listenersSet == listeners.end ()) {
36+ bool shouldInstallMonitor = false ;
37+ {
38+ std::lock_guard<std::mutex> lock (listenersMutex);
39+ auto listenersSet = listeners.find (&rt);
40+ if (listenersSet == listeners.end ()) {
41+ std::unordered_set<RuntimeLifecycleListener *> newSet;
42+ newSet.insert (listener);
43+ listeners.emplace (&rt, std::move (newSet));
44+ shouldInstallMonitor = true ;
45+ } else {
46+ listenersSet->second .insert (listener);
47+ }
48+ }
49+ if (shouldInstallMonitor) {
3150 // We install a global host object in the provided runtime, this way we can
3251 // use that host object destructor to get notified when the runtime is being
3352 // terminated. We use a unique name for the object as it gets saved with the
@@ -36,16 +55,12 @@ void RuntimeLifecycleMonitor::addListener(jsi::Runtime &rt,
3655 rt, " __rnskia_rt_lifecycle_monitor" ,
3756 jsi::Object::createFromHostObject (
3857 rt, std::make_shared<RuntimeLifecycleMonitorObject>(&rt)));
39- std::unordered_set<RuntimeLifecycleListener *> newSet;
40- newSet.insert (listener);
41- listeners.emplace (&rt, std::move (newSet));
42- } else {
43- listenersSet->second .insert (listener);
4458 }
4559}
4660
4761void RuntimeLifecycleMonitor::removeListener (
4862 jsi::Runtime &rt, RuntimeLifecycleListener *listener) {
63+ std::lock_guard<std::mutex> lock (listenersMutex);
4964 auto listenersSet = listeners.find (&rt);
5065 if (listenersSet == listeners.end ()) {
5166 // nothing to do here
0 commit comments