aboutsummaryrefslogtreecommitdiff
path: root/src/stable/counterevent.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/counterevent.h')
-rw-r--r--src/stable/counterevent.h154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/stable/counterevent.h b/src/stable/counterevent.h
new file mode 100644
index 0000000..e7ad7a1
--- /dev/null
+++ b/src/stable/counterevent.h
@@ -0,0 +1,154 @@
1/*
2 * Copyright (C) 2007-2019 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_COUNTER_EVENT_H
9#define BU_COUNTER_EVENT_H
10
11#include <pthread.h>
12
13#include "bu/mutex.h"
14#include "bu/condition.h"
15
16namespace Bu
17{
18 /**
19 * Represents a true/false state that controls thread synchronization. This
20 * is primarilly intended to control the synchronization state of
21 * multithreaded services. For example, telling all threads when to exit.
22 *
23 * An Event is either set or unset. If the Event is unset then it can be
24 * waited on for something to happen. As soon as the Event is set all
25 * waiting threads are released and new requests to wait are ignored until
26 * the Event is cleared again.
27 *
28 * Threads can also be woken up without setting the Event, which may be
29 * handy in certain circumstances.
30 *@ingroup Threading
31 */
32 class CounterEvent
33 {
34 public:
35 CounterEvent() :
36 iCount( 0 )
37 {
38 }
39
40 ~CounterEvent()
41 {
42 }
43
44 /**
45 * Wait indefinitely for the Event to trigger. If the event is already
46 * set, then return immediately. It's important to note that this may
47 * return at any time, not only when the Event is set, so examining the
48 * return value is important.
49 *@returns the set status of the Event.
50 */
51 int wait()
52 {
53 cBlock.lock();
54 if( iCount == 0 )
55 {
56 cBlock.unlock();
57 return iCount;
58 }
59 cBlock.wait();
60 int iRet = iCount;
61 cBlock.unlock();
62 return iRet;
63 }
64
65 /**
66 * Wait for up to nSec seconds and nUSec nanoseconds for the event to
67 * trigger. If the Event is already set then return immediately.
68 *@returns the set status of the Event.
69 */
70 int wait( int nSec, int nUSec )
71 {
72 cBlock.lock();
73 if( iCount == 0 )
74 {
75 cBlock.unlock();
76 return iCount;
77 }
78 cBlock.wait( nSec, nUSec );
79 bool iRet = iCount;
80 cBlock.unlock();
81 return iRet;
82 }
83
84 /**
85 * Allow one of the waiting threads to unlock without updating the set
86 * state of the Event.
87 */
88 void unblockOne()
89 {
90 cBlock.lock();
91 cBlock.signal();
92 cBlock.unlock();
93 }
94
95 /**
96 * Allow all waiting threads to unlock and proceed without updating the
97 * set state of the Event.
98 */
99 void unblockAll()
100 {
101 cBlock.lock();
102 cBlock.broadcast();
103 cBlock.unlock();
104 }
105
106 /**
107 * Find out if the Event is in the set state or not.
108 *@returns True if set, false otherwise.
109 */
110 bool isZero()
111 {
112 cBlock.lock();
113 bool bRet = (iCount == 0);
114 cBlock.unlock();
115 return bRet;
116 }
117
118 /**
119 * Sets the Event's state to true and triggers all waiting threads.
120 */
121 void decrement()
122 {
123 cBlock.lock();
124 iCount--; if( iCount < 0 ) iCount = 0;
125 if( iCount == 0 )
126 cBlock.broadcast();
127 cBlock.unlock();
128 }
129
130 void increment()
131 {
132 cBlock.lock();
133 iCount++;
134 cBlock.unlock();
135 }
136
137 /**
138 * Sets the Event's state to false. This does NOT trigger any waiting
139 * threads.
140 */
141 void clear()
142 {
143 cBlock.lock();
144 iCount = 0;
145 cBlock.unlock();
146 }
147
148 private:
149 Condition cBlock; /**< The condition for blocking dequeues. */
150 int iCount;
151 };
152}
153
154#endif