xref: /aoo42x/main/sal/osl/unx/conditn.c (revision 9b7ebb41)
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 /*****************************************************************************/
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 /*****************************************************************************/
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 /*****************************************************************************/
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        (void)pthread_mutex_unlock(&pCond->m_Lock);
153 	   return sal_False;
154    }
155 
156    nRet = pthread_mutex_unlock(&pCond->m_Lock);
157    if ( nRet != 0 )
158    {
159        OSL_TRACE("osl_setCondition : mutex unlock failed. Errno: %d; %s\n",
160                   nRet, strerror(nRet));
161        return sal_False;
162    }
163 
164    return sal_True;
165 
166 }
167 
168 /*****************************************************************************/
169 /* osl_resetCondition */
170 /*****************************************************************************/
171 sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition)
172 {
173 	oslConditionImpl* pCond;
174     int nRet=0;
175 
176 	OSL_ASSERT(Condition);
177 
178 	pCond = (oslConditionImpl*)Condition;
179 
180 	if ( pCond == 0 )
181 	{
182 		return sal_False;
183 	}
184 
185     nRet = pthread_mutex_lock(&pCond->m_Lock);
186 	if ( nRet != 0 )
187 	{
188        OSL_TRACE("osl_resetCondition : mutex lock failed. Errno: %d; %s\n",
189                   nRet, strerror(nRet));
190 		return sal_False;
191 	}
192 
193 	pCond->m_State = sal_False;
194 
195     nRet = pthread_mutex_unlock(&pCond->m_Lock);
196     if ( nRet != 0 )
197     {
198        OSL_TRACE("osl_resetCondition : mutex unlock failed. Errno: %d; %s\n",
199                   nRet, strerror(nRet));
200         return sal_False;
201     }
202 
203 	return sal_True;
204 }
205 
206 /*****************************************************************************/
207 /* osl_waitCondition */
208 /*****************************************************************************/
209 oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout)
210 {
211 	oslConditionImpl* pCond;
212     int nRet=0;
213 	oslConditionResult Result = osl_cond_result_ok;
214 
215 	OSL_ASSERT(Condition);
216 	pCond = (oslConditionImpl*)Condition;
217 
218 	if ( pCond == 0 )
219 	{
220 		return osl_cond_result_error;
221 	}
222 
223     nRet = pthread_mutex_lock(&pCond->m_Lock);
224 	if ( nRet != 0 )
225 	{
226        OSL_TRACE("osl_waitCondition : mutex lock failed. Errno: %d; %s\n",
227                   nRet, strerror(nRet));
228 		return osl_cond_result_error;
229 	}
230 
231     if ( pTimeout )
232     {
233         if ( ! pCond->m_State )
234         {
235 			int					ret;
236 			struct timeval      tp;
237 			struct timespec		to;
238 
239 			gettimeofday(&tp, NULL);
240 
241 			SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds,
242 							  tp.tv_usec * 1000 + pTimeout->Nanosec );
243 
244             /* spurious wake up prevention */
245             do
246             {
247                 ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to);
248 				if ( ret != 0 )
249 				{
250 					if ( ret == ETIME || ret == ETIMEDOUT )
251 					{
252 						Result = osl_cond_result_timeout;
253                         nRet = pthread_mutex_unlock(&pCond->m_Lock);
254 						if (nRet != 0)
255                         {
256                             OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
257                                       nRet, strerror(nRet));
258                         }
259 
260 						return Result;
261 					}
262 					else if ( ret != EINTR )
263 					{
264 						Result = osl_cond_result_error;
265                         nRet = pthread_mutex_unlock(&pCond->m_Lock);
266 						if ( nRet != 0 )
267                         {
268                             OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
269                                       nRet, strerror(nRet));
270                         }
271 						return Result;
272 					}
273 /*                    OSL_TRACE("EINTR\n");*/
274 				}
275             }
276             while ( !pCond->m_State );
277 		}
278 	}
279     else
280     {
281         while ( !pCond->m_State )
282         {
283             nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock);
284 			if ( nRet != 0 )
285 			{
286                 OSL_TRACE("osl_waitCondition : condition wait failed. Errno: %d; %s\n",
287                           nRet, strerror(nRet));
288 				Result = osl_cond_result_error;
289 				nRet = pthread_mutex_unlock(&pCond->m_Lock);
290                 if ( nRet != 0 )
291                 {
292                     OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
293                               nRet, strerror(nRet));
294                 }
295 
296 				return Result;
297 			}
298 		}
299     }
300 
301 	nRet = pthread_mutex_unlock(&pCond->m_Lock);
302     if ( nRet != 0 )
303     {
304         OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
305                   nRet, strerror(nRet));
306     }
307 
308 	return Result;
309 }
310 
311 /*****************************************************************************/
312 /* osl_checkCondition */
313 /*****************************************************************************/
314 sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition)
315 {
316 	sal_Bool State;
317 	oslConditionImpl* pCond;
318     int nRet=0;
319 
320 	OSL_ASSERT(Condition);
321 	pCond = (oslConditionImpl*)Condition;
322 
323 	if ( pCond == 0 )
324 	{
325 		return sal_False;
326 	}
327 
328 	nRet = pthread_mutex_lock(&pCond->m_Lock);
329     if ( nRet != 0 )
330     {
331         OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n",
332                   nRet, strerror(nRet));
333     }
334 
335 	State = pCond->m_State;
336 
337 	nRet = pthread_mutex_unlock(&pCond->m_Lock);
338     if ( nRet != 0 )
339     {
340         OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n",
341                   nRet, strerror(nRet));
342     }
343 
344 	return State;
345 }
346 
347 
348