11#if LIBKAZV_BUILT_WITH_DEBUG
12#ifndef KAZV_USE_THREAD_SAFETY_HELPER
13#define KAZV_USE_THREAD_SAFETY_HELPER
17#ifdef KAZV_USE_THREAD_SAFETY_HELPER
19struct ThreadNotMatchException
23 std::string what()
const;
26struct EventLoopThreadIdKeeper
28 mutable std::mutex m_mutex;
29 std::optional<std::thread::id> m_id;
32 void set(std::thread::id
id) {
33 std::lock_guard<std::mutex> g(m_mutex);
37 std::optional<std::thread::id> get()
const {
38 std::lock_guard<std::mutex> g(m_mutex);
42#define KAZV_THREAD_ID_VAR _threadSafetyHelper_threadId
43#define KAZV_ON_EVENT_LOOP_VAR _threadSafetyHelper_onEventLoop
44#define KAZV_EVENT_LOOP_THREAD_ID_KEEPER_VAR _threadSafetyHelper_eventLoopThreadIdKeeper
45#define KAZV_DECLARE_THREAD_ID() bool KAZV_ON_EVENT_LOOP_VAR{false}; \
46 std::thread::id KAZV_THREAD_ID_VAR = std::this_thread::get_id();
47#define KAZV_DECLARE_EVENT_LOOP_THREAD_ID_KEEPER(_initializer) \
48 EventLoopThreadIdKeeper *KAZV_EVENT_LOOP_THREAD_ID_KEEPER_VAR = _initializer
50#define KAZV_VERIFY_THREAD_ID() \
52 auto _threadSafetyHelper_local_idActual = std::this_thread::get_id(); \
54 if (KAZV_ON_EVENT_LOOP_VAR) { \
55 auto _threadSafetyHelper_local_idExpected = \
56 KAZV_EVENT_LOOP_THREAD_ID_KEEPER_VAR ? KAZV_EVENT_LOOP_THREAD_ID_KEEPER_VAR->get() : std::nullopt; \
58 _threadSafetyHelper_local_idExpected.has_value() \
59 ? _threadSafetyHelper_local_idExpected.value() == _threadSafetyHelper_local_idActual \
63 throw ThreadNotMatchException{"Current object belongs to the event loop, but method is called outside the event loop"}; \
66 if (! (KAZV_THREAD_ID_VAR == _threadSafetyHelper_local_idActual)) { \
67 throw ThreadNotMatchException{"Current thread id does not match the id of the thread where it belongs"}; \
73#define KAZV_DECLARE_THREAD_ID()
74#define KAZV_VERIFY_THREAD_ID()
75#define KAZV_DECLARE_EVENT_LOOP_THREAD_ID_KEEPER(_initializer)