1 /***************************************************************************
2 * Copyright (C) 2009 by Stefan Fuhrmann *
3 * stefanfuhrmann@alice-dsl.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
22 #include "WaitableEvent.h"
23 #include "CriticalSection.h"
28 // recycler for OS constructs
32 class CWaitableEventPool
36 // multi-threading sync.
38 CCriticalSection mutex
;
40 // allocated, currently usused handles
42 std::vector
<HANDLE
> handles
;
44 // flag indicating that this instance has not been destroyed, yet
48 // construction / destruction:
49 // free all handles upon destruction at latest
52 ~CWaitableEventPool();
58 static CWaitableEventPool
* GetInstance();
60 // recycling interface:
64 void AutoAlloc (HANDLE
& handle
);
65 void Release (HANDLE event
);
69 // construction / destruction:
71 CWaitableEventPool::CWaitableEventPool()
76 CWaitableEventPool::~CWaitableEventPool()
79 InterlockedExchange (&alive
, FALSE
);
84 CWaitableEventPool
* CWaitableEventPool::GetInstance()
86 static CWaitableEventPool instance
;
90 // recycling interface:
93 HANDLE
CWaitableEventPool::Alloc()
95 if (InterlockedCompareExchange (&alive
, TRUE
, TRUE
))
97 CCriticalSectionLock
lock (mutex
);
100 HANDLE result
= handles
.back();
106 return CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
109 void CWaitableEventPool::AutoAlloc (HANDLE
& handle
)
114 if (InterlockedCompareExchange (&alive
, TRUE
, TRUE
))
116 CCriticalSectionLock
lock (mutex
);
117 if (!handles
.empty())
119 handle
= handles
.back();
125 handle
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
128 void CWaitableEventPool::Release (HANDLE event
)
131 if (InterlockedCompareExchange (&alive
, TRUE
, TRUE
))
133 CCriticalSectionLock
lock (mutex
);
134 handles
.push_back (event
);
142 void CWaitableEventPool::Clear()
144 CCriticalSectionLock
lock (mutex
);
146 while (!handles
.empty())
147 CloseHandle (Alloc());
151 // construction / destruction: manage event handle
153 COneShotEvent::COneShotEvent()
159 COneShotEvent::~COneShotEvent()
162 CWaitableEventPool::GetInstance()->Release (event
);
165 // eventing interface
167 void COneShotEvent::Set()
169 if (InterlockedExchange (&state
, TRUE
) == FALSE
)
174 bool COneShotEvent::Test() const
176 return state
== TRUE
;
179 void COneShotEvent::WaitFor()
183 CWaitableEventPool::GetInstance()->AutoAlloc (event
);
185 WaitForSingleObject (event
, INFINITE
);
189 bool COneShotEvent::WaitForEndOrTimeout(DWORD milliSeconds
)
193 CWaitableEventPool::GetInstance()->AutoAlloc (event
);
194 return WaitForSingleObject (event
, milliSeconds
) == WAIT_OBJECT_0
;
200 // construction / destruction: manage event handle
202 CWaitableEvent::CWaitableEvent()
203 : event (CWaitableEventPool::GetInstance()->Alloc())
207 CWaitableEvent::~CWaitableEvent()
209 CWaitableEventPool::GetInstance()->Release (event
);
212 // eventing interface
214 void CWaitableEvent::Set()
219 void CWaitableEvent::Reset()
224 bool CWaitableEvent::Test() const
226 return WaitForSingleObject (event
, 0) == WAIT_OBJECT_0
;
229 void CWaitableEvent::WaitFor()
231 WaitForSingleObject (event
, INFINITE
);
234 bool CWaitableEvent::WaitForEndOrTimeout(DWORD milliSeconds
)
236 return WaitForSingleObject (event
, milliSeconds
) == WAIT_OBJECT_0
;