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 #include "system.h"
25 #include <sal/types.h>
26
27 #include <osl/conditn.h>
28 #include <osl/diagnose.h>
29 #include <osl/time.h>
30
31
32 typedef struct _oslConditionImpl
33 {
34 pthread_cond_t m_Condition;
35 pthread_mutex_t m_Lock;
36 sal_Bool m_State;
37 } oslConditionImpl;
38
39
40 /*****************************************************************************/
41 /* osl_createCondition */
42 /*****************************************************************************/
osl_createCondition()43 oslCondition SAL_CALL osl_createCondition()
44 {
45 oslConditionImpl* pCond;
46 int nRet=0;
47
48 pCond = (oslConditionImpl*) malloc(sizeof(oslConditionImpl));
49
50 OSL_ASSERT(pCond);
51
52 if ( pCond == NULL )
53 {
54 return 0;
55 }
56
57 pCond->m_State = sal_False;
58
59 /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */
60 nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT);
61 if ( nRet != 0 )
62 {
63 OSL_TRACE("osl_createCondition : condition init failed. Errno: %d; '%s'\n",
64 nRet, strerror(nRet));
65
66 free(pCond);
67 return 0;
68 }
69
70 nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT);
71 if ( nRet != 0 )
72 {
73 OSL_TRACE("osl_createCondition : mutex init failed. Errno: %d; %s\n",
74 nRet, strerror(nRet));
75
76 nRet = pthread_cond_destroy(&pCond->m_Condition);
77 if ( nRet != 0 )
78 {
79 OSL_TRACE("osl_createCondition : destroy condition failed. Errno: %d; '%s'\n",
80 nRet, strerror(nRet));
81 }
82
83 free(pCond);
84 pCond = NULL;
85 }
86
87 return (oslCondition)pCond;
88 }
89
90 /*****************************************************************************/
91 /* osl_destroyCondition */
92 /*****************************************************************************/
osl_destroyCondition(oslCondition Condition)93 void SAL_CALL osl_destroyCondition(oslCondition Condition)
94 {
95 oslConditionImpl* pCond;
96 int nRet = 0;
97
98 if ( Condition )
99 {
100 pCond = (oslConditionImpl*)Condition;
101
102 nRet = pthread_cond_destroy(&pCond->m_Condition);
103 if ( nRet != 0 )
104 {
105 OSL_TRACE("osl_destroyCondition : destroy condition failed. Errno: %d; '%s'\n",
106 nRet, strerror(nRet));
107 }
108 nRet = pthread_mutex_destroy(&pCond->m_Lock);
109 if ( nRet != 0 )
110 {
111 OSL_TRACE("osl_destroyCondition : destroy mutex failed. Errno: %d; '%s'\n",
112 nRet, strerror(nRet));
113 }
114
115 free(Condition);
116 }
117
118 return;
119 }
120
121 /*****************************************************************************/
122 /* osl_setCondition */
123 /*****************************************************************************/
osl_setCondition(oslCondition Condition)124 sal_Bool SAL_CALL osl_setCondition(oslCondition Condition)
125 {
126 oslConditionImpl* pCond;
127 int nRet=0;
128
129 OSL_ASSERT(Condition);
130 pCond = (oslConditionImpl*)Condition;
131
132 if ( pCond == NULL )
133 {
134 return sal_False;
135 }
136
137 nRet = pthread_mutex_lock(&pCond->m_Lock);
138 if ( nRet != 0 )
139 {
140 OSL_TRACE("osl_setCondition : mutex lock failed. Errno: %d; %s\n",
141 nRet, strerror(nRet));
142 return sal_False;
143 }
144
145 pCond->m_State = sal_True;
146 nRet = pthread_cond_broadcast(&pCond->m_Condition);
147 if ( nRet != 0 )
148 {
149 OSL_TRACE("osl_setCondition : condition broadcast failed. Errno: %d; %s\n",
150 nRet, strerror(nRet));
151 (void)pthread_mutex_unlock(&pCond->m_Lock);
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 == NULL )
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 == NULL )
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 == NULL )
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