Skip to content

Commit 0afc70e

Browse files
bghgaryCopilot
andcommitted
Add optional testing hook for blocking_concurrent_queue
Add a global before-wait callback invoked while holding the queue mutex, right before condition_variable::wait(). This enables deterministic testing of lost-wakeup race conditions in code that uses the queue. Behind #ifdef ARCANA_TESTING_HOOKS -- zero cost when not enabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 53e5b05 commit 0afc70e

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

Source/Shared/arcana/threading/blocking_concurrent_queue.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
#include <queue>
88
#include <condition_variable>
99

10+
#ifdef ARCANA_TESTING_HOOKS
11+
#include <functional>
12+
inline std::function<void()> g_beforeWaitCallback{[]() {}};
13+
#endif
14+
1015
namespace arcana
1116
{
1217
template<typename T, size_t max_size = std::numeric_limits<size_t>::max()>
@@ -95,6 +100,9 @@ namespace arcana
95100
{
96101
while (!cancel.cancelled() && m_data.empty())
97102
{
103+
#ifdef ARCANA_TESTING_HOOKS
104+
g_beforeWaitCallback();
105+
#endif
98106
m_dataReady.wait(lock);
99107
}
100108
}
@@ -116,6 +124,9 @@ namespace arcana
116124
{
117125
while (!cancel.cancelled() && m_data.empty())
118126
{
127+
#ifdef ARCANA_TESTING_HOOKS
128+
g_beforeWaitCallback();
129+
#endif
119130
m_dataReady.wait(lock);
120131
}
121132
}

Source/Shared/arcana/threading/dispatcher.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ namespace arcana
4545
dispatcher& operator=(dispatcher&&) = default;
4646
dispatcher(dispatcher&&) = default;
4747

48+
#ifdef ARCANA_TESTING_HOOKS
49+
void set_before_wait_callback(std::function<void()> callback)
50+
{
51+
m_work.set_before_wait_callback(std::move(callback));
52+
}
53+
#endif
54+
4855
bool tick(const cancellation& token)
4956
{
5057
return internal_tick(token, false);
@@ -114,6 +121,9 @@ namespace arcana
114121
using dispatcher<WorkSize>::clear;
115122
using dispatcher<WorkSize>::set_affinity;
116123
using dispatcher<WorkSize>::tick;
124+
#ifdef ARCANA_TESTING_HOOKS
125+
using dispatcher<WorkSize>::set_before_wait_callback;
126+
#endif
117127
};
118128

119129
template<size_t WorkSize>

0 commit comments

Comments
 (0)