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
19 struct ThreadNotMatchException
23 std::string what()
const;
26 struct 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)