20 #include <winpr/config.h>
21 #include <winpr/assert.h>
23 #include <winpr/crt.h>
25 #include <winpr/collections.h>
48 size_t CountdownEvent_CurrentCount(wCountdownEvent* countdown)
50 WINPR_ASSERT(countdown);
51 EnterCriticalSection(&countdown->lock);
52 const size_t rc = countdown->count;
53 LeaveCriticalSection(&countdown->lock);
61 size_t CountdownEvent_InitialCount(wCountdownEvent* countdown)
63 WINPR_ASSERT(countdown);
64 EnterCriticalSection(&countdown->lock);
65 const size_t rc = countdown->initialCount;
66 LeaveCriticalSection(&countdown->lock);
74 BOOL CountdownEvent_IsSet(wCountdownEvent* countdown)
78 WINPR_ASSERT(countdown);
79 if (WaitForSingleObject(countdown->event, 0) == WAIT_OBJECT_0)
89 HANDLE CountdownEvent_WaitHandle(wCountdownEvent* countdown)
91 WINPR_ASSERT(countdown);
92 return countdown->event;
103 void CountdownEvent_AddCount(wCountdownEvent* countdown,
size_t signalCount)
105 WINPR_ASSERT(countdown);
106 EnterCriticalSection(&countdown->lock);
108 const BOOL signalSet = countdown->count == 0;
109 countdown->count += signalCount;
112 (void)ResetEvent(countdown->event);
114 LeaveCriticalSection(&countdown->lock);
122 BOOL CountdownEvent_Signal(wCountdownEvent* countdown,
size_t signalCount)
125 BOOL newStatus = FALSE;
126 BOOL oldStatus = FALSE;
128 WINPR_ASSERT(countdown);
130 EnterCriticalSection(&countdown->lock);
132 if (WaitForSingleObject(countdown->event, 0) == WAIT_OBJECT_0)
135 if (signalCount <= countdown->count)
136 countdown->count -= signalCount;
138 countdown->count = 0;
140 if (countdown->count == 0)
143 if (newStatus && (!oldStatus))
145 (void)SetEvent(countdown->event);
149 LeaveCriticalSection(&countdown->lock);
158 void CountdownEvent_Reset(wCountdownEvent* countdown,
size_t count)
160 WINPR_ASSERT(countdown);
161 countdown->initialCount = count;
168 wCountdownEvent* CountdownEvent_New(
size_t initialCount)
170 wCountdownEvent* countdown = (wCountdownEvent*)calloc(1,
sizeof(wCountdownEvent));
175 countdown->count = initialCount;
176 countdown->initialCount = initialCount;
178 if (!InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000))
181 countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL);
182 if (!countdown->event)
185 if (countdown->count == 0)
187 if (!SetEvent(countdown->event))
194 WINPR_PRAGMA_DIAG_PUSH
195 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
196 CountdownEvent_Free(countdown);
197 WINPR_PRAGMA_DIAG_POP
201 void CountdownEvent_Free(wCountdownEvent* countdown)
206 DeleteCriticalSection(&countdown->lock);
207 (void)CloseHandle(countdown->event);