@@ -14,46 +14,29 @@ namespace Babylon::Polyfills::Internal
1414 }
1515 }
1616
17- struct TimeoutDispatcher ::Timeout
18- {
19- TimeoutId id;
20-
21- // Make this non-shared when JsRuntime::Dispatch supports it.
22- std::shared_ptr<Napi::FunctionReference> function;
23-
24- TimePoint time;
25-
26- Timeout (TimeoutId id, std::shared_ptr<Napi::FunctionReference> function, TimePoint time)
27- : id{id}
28- , function{std::move (function)}
29- , time{time}
30- {
31- }
32-
33- Timeout (const Timeout&) = delete ;
34- Timeout (Timeout&&) = delete ;
35- };
36-
3717 TimeoutDispatcher::TimeoutDispatcher (Babylon::JsRuntime& runtime)
38- : m_runtime {runtime}
18+ : m_runtimeScheduler {runtime}
3919 , m_thread{std::thread{&TimeoutDispatcher::ThreadFunction, this }}
4020 {
4121 }
4222
4323 TimeoutDispatcher::~TimeoutDispatcher ()
4424 {
4525 {
46- std::unique_lock<std::mutex> lk {m_mutex};
26+ std::unique_lock<std::mutex> lock {m_mutex};
4727 m_idMap.clear ();
4828 m_timeMap.clear ();
4929 }
5030
51- m_shutdown = true ;
31+ m_cancellationSource. cancel () ;
5232 m_condVariable.notify_one ();
5333 m_thread.join ();
34+
35+ // Wait for async operations to complete.
36+ m_runtimeScheduler.Rundown ();
5437 }
5538
56- TimeoutDispatcher:: TimeoutId TimeoutDispatcher::Dispatch (std::shared_ptr<Napi::FunctionReference> function, std::chrono::milliseconds delay)
39+ TimeoutId TimeoutDispatcher::Dispatch (std::shared_ptr<Napi::FunctionReference> function, std::chrono::milliseconds delay)
5740 {
5841 if (delay.count () < 0 )
5942 {
@@ -70,7 +53,8 @@ namespace Babylon::Polyfills::Internal
7053
7154 if (time <= earliestTime)
7255 {
73- m_runtime.Dispatch ([this ](Napi::Env) {
56+ m_runtimeScheduler.Get ()([this ]()
57+ {
7458 m_condVariable.notify_one ();
7559 });
7660 }
@@ -102,7 +86,7 @@ namespace Babylon::Polyfills::Internal
10286 }
10387 }
10488
105- TimeoutDispatcher:: TimeoutId TimeoutDispatcher::NextTimeoutId ()
89+ TimeoutId TimeoutDispatcher::NextTimeoutId ()
10690 {
10791 while (true )
10892 {
@@ -122,11 +106,11 @@ namespace Babylon::Polyfills::Internal
122106
123107 void TimeoutDispatcher::ThreadFunction ()
124108 {
125- while (!m_shutdown )
109+ while (!m_cancellationSource. cancelled () )
126110 {
127- std::unique_lock<std::mutex> lk{m_mutex};
128- TimePoint nextTimePoint{};
111+ std::unique_lock<std::mutex> lock{m_mutex};
129112
113+ TimePoint nextTimePoint{};
130114 while (!m_timeMap.empty ())
131115 {
132116 nextTimePoint = m_timeMap.begin ()->second ->time ;
@@ -135,7 +119,7 @@ namespace Babylon::Polyfills::Internal
135119 break ;
136120 }
137121
138- m_condVariable.wait_until (lk , nextTimePoint);
122+ m_condVariable.wait_until (lock , nextTimePoint);
139123 }
140124
141125 while (!m_timeMap.empty () && m_timeMap.begin ()->second ->time == nextTimePoint)
@@ -147,9 +131,9 @@ namespace Babylon::Polyfills::Internal
147131 CallFunction (std::move (function));
148132 }
149133
150- while (!m_shutdown && m_timeMap.empty ())
134+ while (!m_cancellationSource. cancelled () && m_timeMap.empty ())
151135 {
152- m_condVariable.wait (lk );
136+ m_condVariable.wait (lock );
153137 }
154138 }
155139 }
@@ -158,7 +142,10 @@ namespace Babylon::Polyfills::Internal
158142 {
159143 if (function)
160144 {
161- m_runtime.Dispatch ([function = std::move (function)](Napi::Env) { function->Call ({}); });
145+ m_runtimeScheduler.Get ()([function = std::move (function)]()
146+ {
147+ function->Call ({});
148+ });
162149 }
163150 }
164151}
0 commit comments