source: vscpl/src/hu/varadiistvan/scpl/_win32/CondVar.h@ 5:55892b4e7748

Last change on this file since 5:55892b4e7748 was 5:55892b4e7748, checked in by István Váradi <ivaradi@…>, 11 years ago

Imported the conditional variable implementation from xplcommon

File size: 4.8 KB
Line 
1// Copyright (c) 2013 by István Váradi
2
3// This file is part of VSCPL, a simple cross-platform utility library
4
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7
8// 1. Redistributions of source code must retain the above copyright notice, this
9// list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25// The views and conclusions contained in the software and documentation are those
26// of the authors and should not be interpreted as representing official policies,
27// either expressed or implied, of the FreeBSD Project.
28
29#ifndef HU_VARADIISTVAN_SCPL_CONDVAR_H
30#define HU_VARADIISTVAN_SCPL_CONDVAR_H
31//------------------------------------------------------------------------------
32
33#include "Mutex.h"
34
35//------------------------------------------------------------------------------
36
37namespace hu { namespace varadiistvan { namespace scpl {
38
39//------------------------------------------------------------------------------
40
41
42/**
43 * A condition variable for the Win32 API.
44 *
45 * Note: the CONDITION_VARIABLE structure and the associated functions
46 * are available only starting with the Windows Vista API. However,
47 * for the time being we also want to support Windows XP, hence this
48 * rather fancy implementation.
49 */
50class CondVar
51{
52private:
53 /**
54 * The mutex protecting the internal data structures.
55 */
56 Mutex mutex;
57
58 /**
59 * The number of waiters.
60 */
61 size_t numWaiters;
62
63 /**
64 * The wait generation.
65 */
66 size_t waitGeneration;
67
68 /**
69 * The number of waiters to release.
70 */
71 size_t numToRelease;
72
73 /**
74 * The event to use for waiting.
75 */
76 HANDLE event;
77
78public:
79 /**
80 * Construct the condition variable.
81 */
82 CondVar();
83
84 /**
85 * Destroy the condition variable.
86 */
87 ~CondVar();
88
89 /**
90 * Wait for the condition variable.
91 *
92 * @param mutex the mutex to unlock and re-lock.
93 * @param timeout the number of milliseconds to wait at most. If
94 * negative, the function will wait indefinitely.
95 *
96 * @return true, if the condition variable was signalled, false
97 * if a timeout occured
98 */
99 bool wait(Mutex& inMutex, int timeout = -1);
100
101 /**
102 * Signal the condition variable to wake up one thread.
103 */
104 void signal();
105
106 /**
107 * Signal all threads waiting on the condition variable.
108 */
109 void broadcast();
110};
111
112//------------------------------------------------------------------------------
113// Inline definitions
114//------------------------------------------------------------------------------
115
116inline CondVar::CondVar() :
117 numWaiters(0),
118 waitGeneration(0),
119 numToRelease(0)
120{
121 event = CreateEvent(0, true, false, 0);
122}
123
124//------------------------------------------------------------------------------
125
126inline CondVar::~CondVar()
127{
128 CloseHandle(event);
129}
130
131//------------------------------------------------------------------------------
132
133inline void CondVar::signal()
134{
135 mutex.lock();
136 if (numWaiters>numToRelease) {
137 SetEvent(event);
138 ++numToRelease;
139 ++waitGeneration;
140 }
141 mutex.unlock();
142}
143
144//------------------------------------------------------------------------------
145
146inline void CondVar::broadcast()
147{
148 mutex.lock();
149 if (numWaiters>0) {
150 SetEvent(event);
151 numToRelease = numWaiters;
152 ++waitGeneration;
153 }
154 mutex.unlock();
155}
156
157//------------------------------------------------------------------------------
158
159} /* namespace hu::varadiistvan::scpl */ } /* namespace hu::varadiistvan */ } /* namespace hu */
160
161//------------------------------------------------------------------------------
162#endif // HU_VARADIISTVAN_SCPL_CONDVAR_H
163
164// Local Variables:
165// mode: C++
166// c-basic-offset: 4
167// indent-tabs-mode: nil
168// End:
Note: See TracBrowser for help on using the repository browser.