xref: /aoo4110/main/sal/osl/unx/conditn.c (revision b1cdbd2c)
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