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 timeSpec;
187 timeSpec.tv_sec = ms / 1000;
188 timeSpec.tv_nsec = (ms - timeSpec.tv_sec * 1000) * 1000000;
189
190 int res = pthread_cond_timedwait(&this->cond, &this->mutex, &timeSpec);
191
192 if (ETIMEDOUT == res)
193 {
194 timeOutOccured = true;
195 }
196 }
197 } while(!locked && !timeOutOccured);
198 pthread_mutex_unlock(&this->mutex);
199 return !timeOutOccured;
200}
201
202//------------------------------------------------------------------------------
205inline bool
207{
208 return this->status != SIGNAL_NONE;
209}
210
211//------------------------------------------------------------------------------
214inline void
216{
217 pthread_mutex_lock(&this->mutex);
218 this->status = SIGNAL_NONE;
219 pthread_mutex_unlock(&this->mutex);
220}
221
222//------------------------------------------------------------------------------
225inline bool
227{
228 return this->manualReset;
229}
230
231} // namespace Linux
232//------------------------------------------------------------------------------
233
void Reset()
manually reset the event
Definition linuxevent.h:215
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:206
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:226
~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