summaryrefslogtreecommitdiff
path: root/utils/Semaphore.cpp (plain)
blob: 9717f2e874f72f91c2931ce59744180fab38f401
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18
19#include "Semaphore.h"
20#include "ErrorUtils.h"
21#include <utils/Log.h>
22#include <time.h>
23
24namespace android {
25
26/**
27 @brief Constructor for the semaphore class
28
29 @param none
30 @return none
31 */
32Semaphore::Semaphore()
33{
34 ///Initialize the semaphore to NULL
35 mSemaphore = NULL;
36}
37
38/**
39 @brief Destructor of the semaphore class
40
41 @param none
42 @return none
43
44 */
45Semaphore::~Semaphore()
46{
47 Release();
48}
49
50/**
51 @brief: Releases semaphore
52
53 @param count >=0
54 @return NO_ERROR On Success
55 @return One of the android error codes based on semaphore de-initialization
56 */
57
58status_t Semaphore::Release()
59{
60 int status = 0;
61
62 ///Destroy only if the semaphore has been created
63 if(mSemaphore)
64 {
65 status = sem_destroy(mSemaphore);
66
67 free(mSemaphore);
68
69 mSemaphore = NULL;
70 }
71
72 ///Initialize the semaphore and return the status
73 return ErrorUtils::posixToAndroidError(status);
74
75}
76
77/**
78 @brief Create the semaphore with initial count value
79
80 @param count >=0
81 @return NO_ERROR On Success
82 @return NO_MEMORY If unable to allocate memory for the semaphore
83 @return BAD_VALUE If an invalid count value is passed (<0)
84 @return One of the android error codes based on semaphore initialization
85 */
86
87status_t Semaphore::Create(int count)
88{
89 status_t ret = NO_ERROR;
90
91 ///count cannot be less than zero
92 if(count<0)
93 {
94 return BAD_VALUE;
95 }
96
97 ret = Release();
98 if ( NO_ERROR != ret )
99 {
100 return ret;
101 }
102
103 ///allocate memory for the semaphore
104 mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ;
105
106 ///if memory is unavailable, return error
107 if(!mSemaphore)
108 {
109 return NO_MEMORY;
110 }
111
112 ///Initialize the semaphore and return the status
113 return ErrorUtils::posixToAndroidError(sem_init(mSemaphore, 0x00, count));
114
115}
116
117/**
118 @brief Wait operation
119
120 @param none
121 @return BAD_VALUE if the semaphore is not initialized
122 @return NO_ERROR On success
123 @return One of the android error codes based on semaphore wait operation
124 */
125status_t Semaphore::Wait()
126{
127 ///semaphore should have been created first
128 if(!mSemaphore)
129 {
130 return BAD_VALUE;
131 }
132
133 ///Wait and return the status after signalling
134 return ErrorUtils::posixToAndroidError(sem_wait(mSemaphore));
135
136
137}
138
139
140/**
141 @brief Signal operation
142
143 @param none
144 @return BAD_VALUE if the semaphore is not initialized
145 @return NO_ERROR On success
146 @return One of the android error codes based on semaphore signal operation
147 */
148
149status_t Semaphore::Signal()
150{
151 ///semaphore should have been created first
152 if(!mSemaphore)
153 {
154 return BAD_VALUE;
155 }
156
157 ///Post to the semaphore
158 return ErrorUtils::posixToAndroidError(sem_post(mSemaphore));
159
160}
161
162/**
163 @brief Current semaphore count
164
165 @param none
166 @return Current count value of the semaphore
167 */
168int Semaphore::Count()
169{
170 int val;
171
172 ///semaphore should have been created first
173 if(!mSemaphore)
174 {
175 return BAD_VALUE;
176 }
177
178 ///get the value of the semaphore
179 sem_getvalue(mSemaphore, &val);
180
181 return val;
182}
183
184/**
185 @brief Wait operation with a timeout
186
187 @param timeoutMicroSecs The timeout period in micro seconds
188 @return BAD_VALUE if the semaphore is not initialized
189 @return NO_ERROR On success
190 @return One of the android error codes based on semaphore wait operation
191 */
192
193status_t Semaphore::WaitTimeout(int timeoutMicroSecs)
194{
195 status_t ret = NO_ERROR;
196
197 struct timespec timeSpec;
198 struct timeval currentTime;
199
200 ///semaphore should have been created first
201 if( NULL == mSemaphore)
202 {
203 ret = BAD_VALUE;
204 }
205
206 if ( NO_ERROR == ret )
207 {
208
209 ///setup the timeout values - timeout is specified in seconds and nanoseconds
210 gettimeofday(&currentTime, NULL);
211 timeSpec.tv_sec = currentTime.tv_sec;
212 timeSpec.tv_nsec = currentTime.tv_usec * 1000;
213 timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 );
214 timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000;
215
216 ///Wait for the timeout or signal and return the result based on whichever event occurred first
217 ret = sem_timedwait(mSemaphore, &timeSpec);
218 }
219
220 if ( NO_ERROR != ret )
221 {
222 Signal();
223 Create(0);
224 }
225
226 return ret;
227}
228
229
230};
231
232
233