• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
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
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 // -*- c++ -*-
19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20 
21 
22 //                  OSCL_S E M A P H O R E (S E M A P H O R E  I M P L E M E N T A T I O N)
23 
24 
25 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
26 
27 /*! \file oscl_semaphore.cpp .This file provides SEMAPHORE implementation that can be ported
28 to three OS LINUX, SYMBIAN, WIN32
29 */
30 
31 // Implementation file for OSCL Semaphores
32 #include "oscl_semaphore.h"
33 #include "oscl_assert.h"
34 
35 
36 
37 // Class contructor
OsclSemaphore()38 OSCL_EXPORT_REF OsclSemaphore::OsclSemaphore()
39 {
40     bCreated = false;
41 }
42 
~OsclSemaphore()43 OSCL_EXPORT_REF OsclSemaphore::~OsclSemaphore()
44 {
45     //make sure it was closed
46     OSCL_ASSERT(!bCreated);
47 }
48 
49 
50 /**
51  * Creates the Semaphore
52  *
53  * @param Intialcount & Maximum count
54  *
55  * @return Returns the Error whether it is success or failure.
56  * Incase of failure it will return what is the specific error
57  */
Create(uint32 InitialCount)58 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclSemaphore::Create(uint32 InitialCount)
59 {
60     if (bCreated)
61         return OsclProcStatus::INVALID_OPERATION_ERROR;
62 
63 
64     iCount = InitialCount;
65     if (pthread_cond_init(&ObjCondition, NULL) == 0
66             && pthread_mutex_init(&ObjMutex, NULL) == 0)
67     {
68         bCreated = true;
69         return OsclProcStatus::SUCCESS_ERROR;
70     }
71     return OsclProcStatus::OTHER_ERROR;
72 
73 }
74 
75 
76 /**
77  * Closes the Semaphore
78  *
79  * @param It wont take any parameters
80  *
81  * @return Returns the Error whether it is success or failure.
82  * Incase of failure it will return what is the specific error
83  */
Close(void)84 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclSemaphore::Close(void)
85 {
86     if (!bCreated)
87         return OsclProcStatus::INVALID_OPERATION_ERROR;
88 
89     bCreated = false;
90     return OsclProcStatus::SUCCESS_ERROR;
91 
92 }
93 
94 
95 
96 /**
97  * Waits for access to the  Semaphore
98  *
99  * @param It wont take any parameters
100  *
101  * @return Returns the Error whether it is success or failure
102  * Incase of failure it will return what is the specific error
103  */
Wait()104 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclSemaphore::Wait()
105 {
106     if (!bCreated)
107         return OsclProcStatus::INVALID_OPERATION_ERROR;
108 
109 
110     int res = pthread_mutex_lock(&ObjMutex);
111     if (res != 0)
112         return OsclProcStatus::OTHER_ERROR;
113     while (iCount == 0 && res == 0)
114     {   // wait till the semaphore is signaled
115         // or an error has occurred
116         res = pthread_cond_wait(&ObjCondition, &ObjMutex);
117     }
118     if (res == 0)
119     {   // signaled
120         iCount--;
121     }
122     pthread_mutex_unlock(&ObjMutex);
123     if (res != 0)
124     {   // error occurred
125         // invalid condition or mutex
126         return OsclProcStatus::OTHER_ERROR;
127     }
128     return OsclProcStatus::SUCCESS_ERROR;
129 
130 }
131 
132 #include "osclconfig_time.h"
getAbsTime(struct timespec & abs,uint32 timeout_msec)133 static void getAbsTime(struct timespec &abs, uint32 timeout_msec)
134 {
135     //convert timeout msec to sec + usec.
136     uint32 timeout_sec = timeout_msec / 1000;
137     uint32 timeout_usec = (timeout_msec % 1000) * 1000;
138 
139     //compute target time = time now plus timeout.
140 
141     struct timeval timenow;
142     gettimeofday(&timenow, NULL);
143 
144     uint32 targ_sec = timenow.tv_sec + timeout_sec;
145     uint32 targ_usec = timenow.tv_usec + timeout_usec;
146     while (targ_usec >= 1000000)
147     {
148         targ_sec++;
149         targ_usec -= 1000000;
150     }
151 
152     //convert target time to timespec.
153     abs.tv_sec = targ_sec;
154     abs.tv_nsec = targ_usec * 1000;
155 }
156 
157 /**
158  * Makes the thread to wait on the Semaphore, with a timeout.
159  *
160  * @param timeout in milliseconds.
161  *
162  * @return Returns WAIT_TIMEOUT_ERROR if the timeout expires,
163  * SUCCESS_ERROR if the semaphore is obtained, or in
164  * case of failure it will return what is the specific error
165  */
Wait(uint32 timeout_msec)166 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclSemaphore::Wait(uint32 timeout_msec)
167 {
168     if (!bCreated)
169         return OsclProcStatus::INVALID_OPERATION_ERROR;
170 
171 
172     int res = pthread_mutex_lock(&ObjMutex);
173     if (res != 0)
174         return OsclProcStatus::OTHER_ERROR;
175     if (iCount > 0)
176     {
177         iCount--;
178         pthread_mutex_unlock(&ObjMutex);
179         return OsclProcStatus::SUCCESS_ERROR;
180     }
181 
182     struct timespec abs;
183     getAbsTime(abs, timeout_msec);
184 
185     while ((iCount == 0) && (res == 0))
186     {   // wait till semaphore is signaled
187         // or time runs out
188         res = pthread_cond_timedwait(&ObjCondition, &ObjMutex, &abs);
189     }
190     if (res == 0)
191     {   // signalied
192         iCount--;
193     }
194     pthread_mutex_unlock(&ObjMutex);
195     if (res == ETIMEDOUT)
196     {   // timeour occurred
197         return OsclProcStatus::WAIT_TIMEOUT_ERROR;
198     }
199     else if (res != 0)
200     {   // error occurred
201         return OsclProcStatus::OTHER_ERROR;
202     }
203     return OsclProcStatus::SUCCESS_ERROR;
204 
205 }
206 
207 /**
208  * Try to acquire semaphore, if the semaphore is already acquired by another thread,
209  *  calling thread immediately returns with out blocking
210  *
211  * @param It wont take any parameters
212  *
213  * @return Returns the Error whether it is success or failure
214  * Incase of failure it will return what is the specific error
215  */
TryWait()216 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclSemaphore::TryWait()
217 {
218     if (!bCreated)
219         return OsclProcStatus::INVALID_OPERATION_ERROR;
220 
221 
222     int res = pthread_mutex_lock(&ObjMutex);
223     if (res != 0)
224         return OsclProcStatus::OTHER_ERROR;
225     if (iCount > 0)
226     {//take it
227         iCount--;
228         pthread_mutex_unlock(&ObjMutex);
229         return OsclProcStatus::SUCCESS_ERROR;
230     }
231     else
232     {//can't take it now so don't block.
233         pthread_mutex_unlock(&ObjMutex);
234         return OsclProcStatus::SEM_NOT_SIGNALED_ERROR;
235     }
236 
237 }
238 
239 
240 /**
241  * Signals that the thread is finished with the Semaphore
242  *
243  * @param It wont take any parameters
244  *
245  * @return Returns the Error whether it is success or failure
246  * Incase of failure it will return what is the specific error
247  */
Signal()248 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclSemaphore::Signal()
249 {
250     if (!bCreated)
251         return OsclProcStatus::INVALID_OPERATION_ERROR;
252 
253 
254     int res = pthread_mutex_lock(&ObjMutex);
255     if (res != 0)
256         return OsclProcStatus::OTHER_ERROR;
257     iCount++;
258     res = pthread_cond_signal(&ObjCondition);
259     pthread_mutex_unlock(&ObjMutex);
260     if (res != 0)
261         return OsclProcStatus::OTHER_ERROR;
262     return OsclProcStatus::SUCCESS_ERROR;
263 
264 
265 }
266 
267