Nebula
Loading...
Searching...
No Matches
linuxevent.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
11#include "core/types.h"
12#include <bits/pthreadtypes.h>
13
14//------------------------------------------------------------------------------
15namespace Linux
16{
18{
19public:
21 LinuxEvent(bool manualReset=false);
25 LinuxEvent(const LinuxEvent& ev) = default;
29 void Signal();
31 void Wait() const;
33 bool WaitTimeout(int ms) const;
35 bool Peek() const;
37 void Reset();
39 bool IsManual() const;
40
42 LinuxEvent& operator=(const LinuxEvent& ev) = default;
43
44private:
45 // emulate windows event behaviour (*sigh*)
47 {
51 };
52
53 mutable pthread_mutex_t mutex;
54 mutable pthread_cond_t cond;
55
57 volatile mutable EventStatus status;
58};
59
60//------------------------------------------------------------------------------
63inline
65 : manualReset(manual)
67{
68 // setup the mutex
69 int res = pthread_mutex_init(&this->mutex, nullptr);
70 n_assert(0 == res);
71
72 // setup the condition variable
73 res = pthread_cond_init(&this->cond, nullptr);
74 n_assert(0 == res);
75}
76
77//------------------------------------------------------------------------------
80inline
82{
83 int res = pthread_cond_destroy(&this->cond);
84 n_assert(0 == res);
85 res = pthread_mutex_destroy(&this->mutex);
86 n_assert(0 == res);
87
88 this->mutex = ev.mutex;
89 this->cond = ev.cond;
90 this->manualReset = ev.manualReset;
91 this->status = ev.status;
92 ev.mutex = pthread_mutex_t{};
93 ev.cond = pthread_cond_t{};
94 ev.status = SIGNAL_NONE;
95}
96
97//------------------------------------------------------------------------------
100inline
102{
103 int res = pthread_cond_destroy(&this->cond);
104 n_assert(0 == res);
105 res = pthread_mutex_destroy(&this->mutex);
106 n_assert(0 == res);
107}
108
109//------------------------------------------------------------------------------
112inline void
114{
115 pthread_mutex_lock(&this->mutex);
116 if(this->manualReset)
117 {
118 this->status = SIGNAL_ALL;
119 pthread_cond_broadcast(&this->cond);
120 }
121 else
122 {
123 this->status = SIGNAL_ONE;
124 pthread_cond_signal(&this->cond);
125 }
126 pthread_mutex_unlock(&this->mutex);
127}
128
129//------------------------------------------------------------------------------
132inline void
134{
135 pthread_mutex_lock(&this->mutex);
136
137 bool locked = false;
138 do
139 {
140 // dont wait for cond if already triggered
141 if (this->status == SIGNAL_ONE)
142 {
143 this->status = SIGNAL_NONE;
144 locked = true;
145 }
146 else if( this->status == SIGNAL_ALL)
147 {
148 // we are in a manual reset event, do nothing
149 locked = true;
150 }
151 else
152 {
153 // we actually have to wait
154 int res = pthread_cond_wait(&this->cond, &this->mutex);
155 n_assert(res == 0);
156 }
157 } while (!locked);
158 pthread_mutex_unlock(&this->mutex);
159}
160
161//------------------------------------------------------------------------------
164inline bool
166{
167 bool timeOutOccured = false;
168 pthread_mutex_lock(&this->mutex);
169
170 bool locked = false;
171 do
172 {
173 // dont wait for cond if already triggered
174 if (this->status == SIGNAL_ONE)
175 {
176 this->status = SIGNAL_NONE;
177 locked = true;
178 }
179 else if( this->status == SIGNAL_ALL)
180 {
181 // we are in a manual reset event, do nothing
182 locked = true;
183 }
184 else
185 {
186 timespec target;
187 clock_gettime(CLOCK_REALTIME, &target);
188 int secs = ms / 1000;
189 time_t remainder = (ms - secs * 1000L);
190 target.tv_sec += secs;
191 target.tv_nsec += remainder * 1000000L;
192
193 int res = pthread_cond_timedwait(&this->cond, &this->mutex, &target);
194
195 if (ETIMEDOUT == res)
196 {
197 timeOutOccured = true;
198 }
199 }
200 } while(!locked && !timeOutOccured);
201 pthread_mutex_unlock(&this->mutex);
202 return !timeOutOccured;
203}
204
205//------------------------------------------------------------------------------
208inline bool
210{
211 return this->status != SIGNAL_NONE;
212}
213
214//------------------------------------------------------------------------------
217inline void
219{
220 pthread_mutex_lock(&this->mutex);
221 this->status = SIGNAL_NONE;
222 pthread_mutex_unlock(&this->mutex);
223}
224
225//------------------------------------------------------------------------------
228inline bool
230{
231 return this->manualReset;
232}
233
234} // namespace Linux
235//------------------------------------------------------------------------------
236
void Reset()
manually reset the event
Definition linuxevent.h:218
LinuxEvent(const LinuxEvent &ev)=default
copy constructor
LinuxEvent & operator=(const LinuxEvent &ev)=default
copy assignment operator
bool WaitTimeout(int ms) const
wait for the event with timeout in millisecs, resets the event
Definition linuxevent.h:165
bool manualReset
Definition linuxevent.h:56
EventStatus
Definition linuxevent.h:47
@ SIGNAL_ALL
Definition linuxevent.h:50
@ SIGNAL_ONE
Definition linuxevent.h:49
@ SIGNAL_NONE
Definition linuxevent.h:48
pthread_mutex_t mutex
Definition linuxevent.h:53
bool Peek() const
check if event is signaled
Definition linuxevent.h:209
void Signal()
signal the event
Definition linuxevent.h:113
void Wait() const
wait for the event to become signalled, resets the event
Definition linuxevent.h:133
pthread_cond_t cond
Definition linuxevent.h:54
bool IsManual() const
Returns true if event is manually reset.
Definition linuxevent.h:229
~LinuxEvent()
destructor
Definition linuxevent.h:101
volatile EventStatus status
Definition linuxevent.h:57
LinuxEvent(bool manualReset=false)
constructor
Definition linuxevent.h:64
#define n_assert(exp)
Definition debug.h:50
Definition linuxcompletioncounter.h:15