Skip to content

Commit def047c

Browse files
committed
Better fix for work queue shutdown issue
1 parent 77dc8f3 commit def047c

File tree

3 files changed

+14
-40
lines changed

3 files changed

+14
-40
lines changed

Core/AppRuntime/Source/WorkQueue.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,19 @@ namespace Babylon
4040

4141
void WorkQueue::Run(Napi::Env env)
4242
{
43-
m_dispatcher.set_affinity(std::this_thread::get_id());
44-
4543
m_env = std::make_optional(env);
4644

45+
m_dispatcher.set_affinity(std::this_thread::get_id());
46+
4747
while (!m_cancellationSource.cancelled())
4848
{
4949
m_dispatcher.blocking_tick(m_cancellationSource);
5050
}
5151

52-
// Drain the queue to complete work dispatched after cancellation.
53-
m_dispatcher.tick(arcana::cancellation::none());
54-
55-
// There should no longer be any outstanding work once the queue is drained.
56-
assert(m_dispatcher.empty());
57-
58-
// Clear the shutdown queue to make sure the callables are destroyed on this thread.
59-
m_shutdownQueue.clear();
52+
// The dispatcher can be non-empty if something is dispatched after cancellation.
53+
// For example, Chakra's JsSetPromiseContinuationCallback may potentially dispatch
54+
// a continuation after cancellation.
55+
m_dispatcher.clear();
6056

6157
m_env.reset();
6258
}

Core/AppRuntime/Source/WorkQueue.h

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,15 @@ namespace Babylon
2323
// copyable callable if necessary.
2424
if constexpr (std::is_copy_constructible<CallableT>::value)
2525
{
26-
if (m_cancellationSource.cancelled())
27-
{
28-
m_shutdownQueue.push([callable = std::move(callable)] {});
29-
}
30-
else
31-
{
32-
m_dispatcher.queue([this, callable = std::move(callable)]() {
33-
callable(m_env.value());
34-
});
35-
}
26+
m_dispatcher.queue([this, callable = std::move(callable)]() {
27+
callable(m_env.value());
28+
});
3629
}
3730
else
3831
{
39-
if (m_cancellationSource.cancelled())
40-
{
41-
m_shutdownQueue.push([callablePtr = std::make_shared<CallableT>(std::move(callable))] {});
42-
}
43-
else
44-
{
45-
m_dispatcher.queue([this, callablePtr = std::make_shared<CallableT>(std::move(callable))]() {
46-
(*callablePtr)(m_env.value());
47-
});
48-
}
32+
m_dispatcher.queue([this, callablePtr = std::make_shared<CallableT>(std::move(callable))]() {
33+
(*callablePtr)(m_env.value());
34+
});
4935
}
5036
}
5137

@@ -55,17 +41,9 @@ namespace Babylon
5541

5642
private:
5743
std::optional<Napi::Env> m_env{};
58-
5944
std::optional<std::scoped_lock<std::mutex>> m_suspensionLock{};
60-
6145
arcana::cancellation_source m_cancellationSource{};
62-
63-
using DispatcherT = arcana::manual_dispatcher<128>;
64-
DispatcherT m_dispatcher{};
65-
66-
// Put the callables in a separate queue during shutdown to ensure the callables are destroyed on the right thread.
67-
arcana::blocking_concurrent_queue<DispatcherT::callback_t> m_shutdownQueue{};
68-
46+
arcana::manual_dispatcher<128> m_dispatcher{};
6947
std::thread m_thread{};
7048
};
7149
}

0 commit comments

Comments
 (0)