1
2
3
4
5
6 #include <cmajor/rt/ConditionVariable.hpp>
7 #include <cmajor/rt/Mutex.hpp>
8 #include <cmajor/rt/Error.hpp>
9 #include <soulng/util/Error.hpp>
10 #include <memory>
11 #include <mutex>
12 #include <condition_variable>
13 #include <stdexcept>
14
15 void* RtAllocateConditionVariable()
16 {
17 return new std::condition_variable_any();
18 }
19
20 void RtFreeConditionVariable(void* nativeHandle)
21 {
22 if (nativeHandle)
23 {
24 delete static_cast<std::condition_variable_any*>(nativeHandle);
25 }
26 }
27
28 int32_t RtNotifyOne(void* nativeHandle)
29 {
30 try
31 {
32 std::condition_variable_any* conditionVariable = static_cast<std::condition_variable_any*>(nativeHandle);
33 conditionVariable->notify_one();
34 return 0;
35 }
36 catch (const std::exception& ex;)
37 {
38 return cmajor::rt::InstallError(ex.what());
39 }
40 }
41
42 int32_t RtNotifyAll(void* nativeHandle)
43 {
44 try
45 {
46 std::condition_variable_any* conditionVariable = static_cast<std::condition_variable_any*>(nativeHandle);
47 conditionVariable->notify_all();
48 return 0;
49 }
50 catch (const std::exception& ex;)
51 {
52 return cmajor::rt::InstallError(ex.what());
53 }
54 }
55
56 int32_t RtWaitConditionVariable(void* nativeHandle, void* recursiveMutexHandle)
57 {
58 try
59 {
60 std::recursive_mutex* recursiveMutex = static_cast<std::recursive_mutex*>(recursiveMutexHandle);
61 std::condition_variable_any* conditionVariable = static_cast<std::condition_variable_any*>(nativeHandle);
62 std::unique_lock<std::recursive_mutex> lock(*recursiveMutex);
63 conditionVariable->wait(lock);
64 return 0;
65 }
66 catch (const std::exception& ex;)
67 {
68 return cmajor::rt::InstallError(ex.what());
69 }
70 }
71
72 enum class CondVarStatus : int32_t
73 {
74 timeout= 0, no_timeout= 1
75 };
76
77 int32_t RtWaitConditionVariableDuration(void* nativeHandle, void* recursiveMutexHandle, int64_t nanoseconds)
78 {
79 try
80 {
81 CondVarStatus status = CondVarStatus::timeout;
82 std::recursive_mutex* recursiveMutex = static_cast<std::recursive_mutex*>(recursiveMutexHandle);
83 std::condition_variable_any* conditionVariable = static_cast<std::condition_variable_any*>(nativeHandle);
84 std::chrono::nanoseconds duration(nanoseconds);
85 std::unique_lock<std::recursive_mutex> lock(*recursiveMutex);
86 if (conditionVariable->wait_for(lock, duration) == std::cv_status::no_timeout)
87 {
88 status = CondVarStatus::no_timeout;
89 }
90 return static_cast<int32_t>(status);
91 }
92 catch (const std::exception& ex;)
93 {
94 return cmajor::rt::InstallError(ex.what());
95 }
96 }