~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to winpr/libwinpr/utils/collections/CountdownEvent.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.1.9) (9.1.17 sid)
  • Revision ID: package-import@ubuntu.com-20141111122050-wyr8hrnwco9fcmum
Tags: 1.1.0~git20140921.1.440916e+dfsg1-2ubuntu1
* Merge with Debian unstable, remaining changes
  - Disable ffmpeg support
* Disable gstreamer support, this relies on gstreamer 0.10 and we don't want
  to add any more deps on that.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * WinPR: Windows Portable Runtime
 
3
 * Countdown Event
 
4
 *
 
5
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * Unless required by applicable law or agreed to in writing, software
 
14
 * distributed under the License is distributed on an "AS IS" BASIS,
 
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
16
 * See the License for the specific language governing permissions and
 
17
 * limitations under the License.
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include "config.h"
 
22
#endif
 
23
 
 
24
#ifdef HAVE_UNISTD_H
 
25
#include <unistd.h>
 
26
#endif
 
27
 
 
28
#include <winpr/crt.h>
 
29
 
 
30
#include <winpr/collections.h>
 
31
 
 
32
/**
 
33
 * C equivalent of the C# CountdownEvent Class
 
34
 * http://msdn.microsoft.com/en-us/library/dd235708/
 
35
 */
 
36
 
 
37
/**
 
38
 * Properties
 
39
 */
 
40
 
 
41
/**
 
42
 * Gets the number of remaining signals required to set the event.
 
43
 */
 
44
 
 
45
DWORD CountdownEvent_CurrentCount(wCountdownEvent* countdown)
 
46
{
 
47
        return countdown->count;
 
48
}
 
49
 
 
50
/**
 
51
 * Gets the numbers of signals initially required to set the event.
 
52
 */
 
53
 
 
54
DWORD CountdownEvent_InitialCount(wCountdownEvent* countdown)
 
55
{
 
56
        return countdown->initialCount;
 
57
}
 
58
 
 
59
/**
 
60
 * Determines whether the event is set.
 
61
 */
 
62
 
 
63
BOOL CountdownEvent_IsSet(wCountdownEvent* countdown)
 
64
{
 
65
        BOOL status = FALSE;
 
66
 
 
67
        if (WaitForSingleObject(countdown->event, 0) == WAIT_OBJECT_0)
 
68
                status = TRUE;
 
69
 
 
70
        return status;
 
71
}
 
72
 
 
73
/**
 
74
 * Gets a WaitHandle that is used to wait for the event to be set.
 
75
 */
 
76
 
 
77
HANDLE CountdownEvent_WaitHandle(wCountdownEvent* countdown)
 
78
{
 
79
        return countdown->event;
 
80
}
 
81
 
 
82
/**
 
83
 * Methods
 
84
 */
 
85
 
 
86
/**
 
87
 * Increments the CountdownEvent's current count by a specified value.
 
88
 */
 
89
 
 
90
void CountdownEvent_AddCount(wCountdownEvent* countdown, DWORD signalCount)
 
91
{
 
92
        EnterCriticalSection(&countdown->lock);
 
93
 
 
94
        countdown->count += signalCount;
 
95
 
 
96
        if (countdown->count > 0)
 
97
                ResetEvent(countdown->event);
 
98
 
 
99
        LeaveCriticalSection(&countdown->lock);
 
100
}
 
101
 
 
102
/**
 
103
 * Registers multiple signals with the CountdownEvent, decrementing the value of CurrentCount by the specified amount.
 
104
 */
 
105
 
 
106
BOOL CountdownEvent_Signal(wCountdownEvent* countdown, DWORD signalCount)
 
107
{
 
108
        BOOL status;
 
109
        BOOL newStatus;
 
110
        BOOL oldStatus;
 
111
 
 
112
        status = newStatus = oldStatus = FALSE;
 
113
 
 
114
        EnterCriticalSection(&countdown->lock);
 
115
 
 
116
        if (WaitForSingleObject(countdown->event, 0) == WAIT_OBJECT_0)
 
117
                oldStatus = TRUE;
 
118
 
 
119
        if (signalCount <= countdown->count)
 
120
                countdown->count -= signalCount;
 
121
        else
 
122
                countdown->count = 0;
 
123
 
 
124
        if (countdown->count == 0)
 
125
                newStatus = TRUE;
 
126
 
 
127
        if (newStatus && (!oldStatus))
 
128
        {
 
129
                SetEvent(countdown->event);
 
130
                status = TRUE;
 
131
        }
 
132
 
 
133
        LeaveCriticalSection(&countdown->lock);
 
134
 
 
135
        return status;
 
136
}
 
137
 
 
138
/**
 
139
 * Resets the InitialCount property to a specified value.
 
140
 */
 
141
 
 
142
void CountdownEvent_Reset(wCountdownEvent* countdown, DWORD count)
 
143
{
 
144
        countdown->initialCount = count;
 
145
}
 
146
 
 
147
/**
 
148
 * Construction, Destruction
 
149
 */
 
150
 
 
151
wCountdownEvent* CountdownEvent_New(DWORD initialCount)
 
152
{
 
153
        wCountdownEvent* countdown = NULL;
 
154
 
 
155
        countdown = (wCountdownEvent*) malloc(sizeof(wCountdownEvent));
 
156
 
 
157
        if (countdown)
 
158
        {
 
159
                countdown->count = initialCount;
 
160
                countdown->initialCount = initialCount;
 
161
                InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000);
 
162
                countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL);
 
163
 
 
164
                if (countdown->count == 0)
 
165
                        SetEvent(countdown->event);
 
166
        }
 
167
 
 
168
        return countdown;
 
169
}
 
170
 
 
171
void CountdownEvent_Free(wCountdownEvent* countdown)
 
172
{
 
173
        DeleteCriticalSection(&countdown->lock);
 
174
        CloseHandle(countdown->event);
 
175
 
 
176
        free(countdown);
 
177
}