1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. 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,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24
25 #include "system.h"
26 #include <sal/types.h>
27
28 #include <osl/conditn.h>
29 #include <osl/diagnose.h>
30 #include <osl/time.h>
31
32
33 typedef struct _oslConditionImpl
34 {
35 pthread_cond_t m_Condition;
36 pthread_mutex_t m_Lock;
37 sal_Bool m_State;
38 } oslConditionImpl;
39
40
41 /*****************************************************************************/
42 /* osl_createCondition */
43 /*****************************************************************************/
osl_createCondition()44 oslCondition SAL_CALL osl_createCondition()
45 {
46 oslConditionImpl* pCond;
47 int nRet=0;
48
49 pCond = (oslConditionImpl*) malloc(sizeof(oslConditionImpl));
50
51 OSL_ASSERT(pCond);
52
53 if ( pCond == 0 )
54 {
55 return 0;
56 }
57
58 pCond->m_State = sal_False;
59
60 /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */
61 nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT);
62 if ( nRet != 0 )
63 {
64 OSL_TRACE("osl_createCondition : condition init failed. Errno: %d; '%s'\n",
65 nRet, strerror(nRet));
66
67 free(pCond);
68 return 0;
69 }
70
71 nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT);
72 if ( nRet != 0 )
73 {
74 OSL_TRACE("osl_createCondition : mutex init failed. Errno: %d; %s\n",
75 nRet, strerror(nRet));
76
77 nRet = pthread_cond_destroy(&pCond->m_Condition);
78 if ( nRet != 0 )
79 {
80 OSL_TRACE("osl_createCondition : destroy condition failed. Errno: %d; '%s'\n",
81 nRet, strerror(nRet));
82 }
83
84 free(pCond);
85 pCond = 0;
86 }
87
88 return (oslCondition)pCond;
89 }
90
91 /*****************************************************************************/
92 /* osl_destroyCondition */
93 /*****************************************************************************/
osl_destroyCondition(oslCondition Condition)94 void SAL_CALL osl_destroyCondition(oslCondition Condition)
95 {
96 oslConditionImpl* pCond;
97 int nRet = 0;
98
99 if ( Condition )
100 {
101 pCond = (oslConditionImpl*)Condition;
102
103 nRet = pthread_cond_destroy(&pCond->m_Condition);
104 if ( nRet != 0 )
105 {
106 OSL_TRACE("osl_destroyCondition : destroy condition failed. Errno: %d; '%s'\n",
107 nRet, strerror(nRet));
108 }
109 nRet = pthread_mutex_destroy(&pCond->m_Lock);
110 if ( nRet != 0 )
111 {
112 OSL_TRACE("osl_destroyCondition : destroy mutex failed. Errno: %d; '%s'\n",
113 nRet, strerror(nRet));
114 }
115
116 free(Condition);
117 }
118
119 return;
120 }
121
122 /*****************************************************************************/
123 /* osl_setCondition */
124 /*****************************************************************************/
osl_setCondition(oslCondition Condition)125 sal_Bool SAL_CALL osl_setCondition(oslCondition Condition)
126 {
127 oslConditionImpl* pCond;
128 int nRet=0;
129
130 OSL_ASSERT(Condition);
131 pCond = (oslConditionImpl*)Condition;
132
133 if ( pCond == 0 )
134 {
135 return sal_False;
136 }
137
138 nRet = pthread_mutex_lock(&pCond->m_Lock);
139 if ( nRet != 0 )
140 {
141 OSL_TRACE("osl_setCondition : mutex lock failed. Errno: %d; %s\n",
142 nRet, strerror(nRet));
143 return sal_False;
144 }
145
146 pCond->m_State = sal_True;
147 nRet = pthread_cond_broadcast(&pCond->m_Condition);
148 if ( nRet != 0 )
149 {
150 OSL_TRACE("osl_setCondition : condition broadcast failed. Errno: %d; %s\n",
151 nRet, strerror(nRet));
152 return sal_False;
153 }
154
155 nRet = pthread_mutex_unlock(&pCond->m_Lock);
156 if ( nRet != 0 )
157 {
158 OSL_TRACE("osl_setCondition : mutex unlock failed. Errno: %d; %s\n",
159 nRet, strerror(nRet));
160 return sal_False;
161 }
162
163 return sal_True;
164
165 }
166
167 /*****************************************************************************/
168 /* osl_resetCondition */
169 /*****************************************************************************/
osl_resetCondition(oslCondition Condition)170 sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition)
171 {
172 oslConditionImpl* pCond;
173 int nRet=0;
174
175 OSL_ASSERT(Condition);
176
177 pCond = (oslConditionImpl*)Condition;
178
179 if ( pCond == 0 )
180 {
181 return sal_False;
182 }
183
184 nRet = pthread_mutex_lock(&pCond->m_Lock);
185 if ( nRet != 0 )
186 {
187 OSL_TRACE("osl_resetCondition : mutex lock failed. Errno: %d; %s\n",
188 nRet, strerror(nRet));
189 return sal_False;
190 }
191
192 pCond->m_State = sal_False;
193
194 nRet = pthread_mutex_unlock(&pCond->m_Lock);
195 if ( nRet != 0 )
196 {
197 OSL_TRACE("osl_resetCondition : mutex unlock failed. Errno: %d; %s\n",
198 nRet, strerror(nRet));
199 return sal_False;
200 }
201
202 return sal_True;
203 }
204
205 /*****************************************************************************/
206 /* osl_waitCondition */
207 /*****************************************************************************/
osl_waitCondition(oslCondition Condition,const TimeValue * pTimeout)208 oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout)
209 {
210 oslConditionImpl* pCond;
211 int nRet=0;
212 oslConditionResult Result = osl_cond_result_ok;
213
214 OSL_ASSERT(Condition);
215 pCond = (oslConditionImpl*)Condition;
216
217 if ( pCond == 0 )
218 {
219 return osl_cond_result_error;
220 }
221
222 nRet = pthread_mutex_lock(&pCond->m_Lock);
223 if ( nRet != 0 )
224 {
225 OSL_TRACE("osl_waitCondition : mutex lock failed. Errno: %d; %s\n",
226 nRet, strerror(nRet));
227 return osl_cond_result_error;
228 }
229
230 if ( pTimeout )
231 {
232 if ( ! pCond->m_State )
233 {
234 int ret;
235 struct timeval tp;
236 struct timespec to;
237
238 gettimeofday(&tp, NULL);
239
240 SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds,
241 tp.tv_usec * 1000 + pTimeout->Nanosec );
242
243 /* spurious wake up prevention */
244 do
245 {
246 ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to);
247 if ( ret != 0 )
248 {
249 if ( ret == ETIME || ret == ETIMEDOUT )
250 {
251 Result = osl_cond_result_timeout;
252 nRet = pthread_mutex_unlock(&pCond->m_Lock);
253 if (nRet != 0)
254 {
255 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
256 nRet, strerror(nRet));
257 }
258
259 return Result;
260 }
261 else if ( ret != EINTR )
262 {
263 Result = osl_cond_result_error;
264 nRet = pthread_mutex_unlock(&pCond->m_Lock);
265 if ( nRet != 0 )
266 {
267 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
268 nRet, strerror(nRet));
269 }
270 return Result;
271 }
272 /* OSL_TRACE("EINTR\n");*/
273 }
274 }
275 while ( !pCond->m_State );
276 }
277 }
278 else
279 {
280 while ( !pCond->m_State )
281 {
282 nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock);
283 if ( nRet != 0 )
284 {
285 OSL_TRACE("osl_waitCondition : condition wait failed. Errno: %d; %s\n",
286 nRet, strerror(nRet));
287 Result = osl_cond_result_error;
288 nRet = pthread_mutex_unlock(&pCond->m_Lock);
289 if ( nRet != 0 )
290 {
291 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
292 nRet, strerror(nRet));
293 }
294
295 return Result;
296 }
297 }
298 }
299
300 nRet = pthread_mutex_unlock(&pCond->m_Lock);
301 if ( nRet != 0 )
302 {
303 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
304 nRet, strerror(nRet));
305 }
306
307 return Result;
308 }
309
310 /*****************************************************************************/
311 /* osl_checkCondition */
312 /*****************************************************************************/
osl_checkCondition(oslCondition Condition)313 sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition)
314 {
315 sal_Bool State;
316 oslConditionImpl* pCond;
317 int nRet=0;
318
319 OSL_ASSERT(Condition);
320 pCond = (oslConditionImpl*)Condition;
321
322 if ( pCond == 0 )
323 {
324 return sal_False;
325 }
326
327 nRet = pthread_mutex_lock(&pCond->m_Lock);
328 if ( nRet != 0 )
329 {
330 OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n",
331 nRet, strerror(nRet));
332 }
333
334 State = pCond->m_State;
335
336 nRet = pthread_mutex_unlock(&pCond->m_Lock);
337 if ( nRet != 0 )
338 {
339 OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n",
340 nRet, strerror(nRet));
341 }
342
343 return State;
344 }
345
346
347