xref: /aoo41x/main/sal/osl/unx/conditn.c (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 #include "system.h"
30 #include <sal/types.h>
31 
32 #include <osl/conditn.h>
33 #include <osl/diagnose.h>
34 #include <osl/time.h>
35 
36 
37 typedef struct _oslConditionImpl
38 {
39 	pthread_cond_t	m_Condition;
40 	pthread_mutex_t	m_Lock;
41 	sal_Bool			m_State;
42 } oslConditionImpl;
43 
44 
45 /*****************************************************************************/
46 /* osl_createCondition */
47 /*****************************************************************************/
48 oslCondition SAL_CALL osl_createCondition()
49 {
50   	oslConditionImpl* pCond;
51     int nRet=0;
52 
53 	pCond = (oslConditionImpl*) malloc(sizeof(oslConditionImpl));
54 
55 	OSL_ASSERT(pCond);
56 
57 	if ( pCond == 0 )
58 	{
59 		return 0;
60 	}
61 
62 	pCond->m_State = sal_False;
63 
64 	/* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */
65     nRet =  pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT);
66 	if ( nRet != 0 )
67 	{
68 	    OSL_TRACE("osl_createCondition : condition init failed. Errno: %d; '%s'\n",
69                   nRet, strerror(nRet));
70 
71 	    free(pCond);
72 		return 0;
73 	}
74 
75     nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT);
76 	if ( nRet != 0 )
77 	{
78 	    OSL_TRACE("osl_createCondition : mutex init failed. Errno: %d; %s\n",
79                   nRet, strerror(nRet));
80 
81         nRet = pthread_cond_destroy(&pCond->m_Condition);
82 	    if ( nRet != 0 )
83         {
84             OSL_TRACE("osl_createCondition : destroy condition failed. Errno: %d; '%s'\n",
85                       nRet, strerror(nRet));
86         }
87 
88         free(pCond);
89 	    pCond = 0;
90 	}
91 
92 	return (oslCondition)pCond;
93 }
94 
95 /*****************************************************************************/
96 /* osl_destroyCondition */
97 /*****************************************************************************/
98 void SAL_CALL osl_destroyCondition(oslCondition Condition)
99 {
100     oslConditionImpl* pCond;
101     int nRet = 0;
102 
103 	if ( Condition )
104 	{
105 	    pCond = (oslConditionImpl*)Condition;
106 
107         nRet = pthread_cond_destroy(&pCond->m_Condition);
108 		if ( nRet != 0 )
109         {
110             OSL_TRACE("osl_destroyCondition : destroy condition failed. Errno: %d; '%s'\n",
111                       nRet, strerror(nRet));
112         }
113         nRet = pthread_mutex_destroy(&pCond->m_Lock);
114 		if ( nRet != 0 )
115         {
116             OSL_TRACE("osl_destroyCondition : destroy mutex failed. Errno: %d; '%s'\n",
117                       nRet, strerror(nRet));
118         }
119 
120 		free(Condition);
121 	}
122 
123     return;
124 }
125 
126 /*****************************************************************************/
127 /* osl_setCondition */
128 /*****************************************************************************/
129 sal_Bool SAL_CALL osl_setCondition(oslCondition Condition)
130 {
131    oslConditionImpl* pCond;
132    int nRet=0;
133 
134    OSL_ASSERT(Condition);
135    pCond = (oslConditionImpl*)Condition;
136 
137    if ( pCond == 0 )
138    {
139 	   return sal_False;
140    }
141 
142    nRet = pthread_mutex_lock(&pCond->m_Lock);
143    if ( nRet != 0 )
144    {
145        OSL_TRACE("osl_setCondition : mutex lock failed. Errno: %d; %s\n",
146                   nRet, strerror(nRet));
147 	   return sal_False;
148    }
149 
150    pCond->m_State = sal_True;
151    nRet = pthread_cond_broadcast(&pCond->m_Condition);
152    if ( nRet != 0 )
153    {
154        OSL_TRACE("osl_setCondition : condition broadcast failed. Errno: %d; %s\n",
155                   nRet, strerror(nRet));
156 	   return sal_False;
157    }
158 
159    nRet = pthread_mutex_unlock(&pCond->m_Lock);
160    if ( nRet != 0 )
161    {
162        OSL_TRACE("osl_setCondition : mutex unlock failed. Errno: %d; %s\n",
163                   nRet, strerror(nRet));
164        return sal_False;
165    }
166 
167    return sal_True;
168 
169 }
170 
171 /*****************************************************************************/
172 /* osl_resetCondition */
173 /*****************************************************************************/
174 sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition)
175 {
176 	oslConditionImpl* pCond;
177     int nRet=0;
178 
179 	OSL_ASSERT(Condition);
180 
181 	pCond = (oslConditionImpl*)Condition;
182 
183 	if ( pCond == 0 )
184 	{
185 		return sal_False;
186 	}
187 
188     nRet = pthread_mutex_lock(&pCond->m_Lock);
189 	if ( nRet != 0 )
190 	{
191        OSL_TRACE("osl_resetCondition : mutex lock failed. Errno: %d; %s\n",
192                   nRet, strerror(nRet));
193 		return sal_False;
194 	}
195 
196 	pCond->m_State = sal_False;
197 
198     nRet = pthread_mutex_unlock(&pCond->m_Lock);
199     if ( nRet != 0 )
200     {
201        OSL_TRACE("osl_resetCondition : mutex unlock failed. Errno: %d; %s\n",
202                   nRet, strerror(nRet));
203         return sal_False;
204     }
205 
206 	return sal_True;
207 }
208 
209 /*****************************************************************************/
210 /* osl_waitCondition */
211 /*****************************************************************************/
212 oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout)
213 {
214 	oslConditionImpl* pCond;
215     int nRet=0;
216 	oslConditionResult Result = osl_cond_result_ok;
217 
218 	OSL_ASSERT(Condition);
219 	pCond = (oslConditionImpl*)Condition;
220 
221 	if ( pCond == 0 )
222 	{
223 		return osl_cond_result_error;
224 	}
225 
226     nRet = pthread_mutex_lock(&pCond->m_Lock);
227 	if ( nRet != 0 )
228 	{
229        OSL_TRACE("osl_waitCondition : mutex lock failed. Errno: %d; %s\n",
230                   nRet, strerror(nRet));
231 		return osl_cond_result_error;
232 	}
233 
234     if ( pTimeout )
235     {
236         if ( ! pCond->m_State )
237         {
238 			int					ret;
239 			struct timeval      tp;
240 			struct timespec		to;
241 
242 			gettimeofday(&tp, NULL);
243 
244 			SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds,
245 							  tp.tv_usec * 1000 + pTimeout->Nanosec );
246 
247             /* spurious wake up prevention */
248             do
249             {
250                 ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to);
251 				if ( ret != 0 )
252 				{
253 					if ( ret == ETIME || ret == ETIMEDOUT )
254 					{
255 						Result = osl_cond_result_timeout;
256                         nRet = pthread_mutex_unlock(&pCond->m_Lock);
257 						if (nRet != 0)
258                         {
259                             OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
260                                       nRet, strerror(nRet));
261                         }
262 
263 						return Result;
264 					}
265 					else if ( ret != EINTR )
266 					{
267 						Result = osl_cond_result_error;
268                         nRet = pthread_mutex_unlock(&pCond->m_Lock);
269 						if ( nRet != 0 )
270                         {
271                             OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
272                                       nRet, strerror(nRet));
273                         }
274 						return Result;
275 					}
276 /*                    OSL_TRACE("EINTR\n");*/
277 				}
278             }
279             while ( !pCond->m_State );
280 		}
281 	}
282     else
283     {
284         while ( !pCond->m_State )
285         {
286             nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock);
287 			if ( nRet != 0 )
288 			{
289                 OSL_TRACE("osl_waitCondition : condition wait failed. Errno: %d; %s\n",
290                           nRet, strerror(nRet));
291 				Result = osl_cond_result_error;
292 				nRet = pthread_mutex_unlock(&pCond->m_Lock);
293                 if ( nRet != 0 )
294                 {
295                     OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
296                               nRet, strerror(nRet));
297                 }
298 
299 				return Result;
300 			}
301 		}
302     }
303 
304 	nRet = pthread_mutex_unlock(&pCond->m_Lock);
305     if ( nRet != 0 )
306     {
307         OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n",
308                   nRet, strerror(nRet));
309     }
310 
311 	return Result;
312 }
313 
314 /*****************************************************************************/
315 /* osl_checkCondition */
316 /*****************************************************************************/
317 sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition)
318 {
319 	sal_Bool State;
320 	oslConditionImpl* pCond;
321     int nRet=0;
322 
323 	OSL_ASSERT(Condition);
324 	pCond = (oslConditionImpl*)Condition;
325 
326 	if ( pCond == 0 )
327 	{
328 		return sal_False;
329 	}
330 
331 	nRet = pthread_mutex_lock(&pCond->m_Lock);
332     if ( nRet != 0 )
333     {
334         OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n",
335                   nRet, strerror(nRet));
336     }
337 
338 	State = pCond->m_State;
339 
340 	nRet = pthread_mutex_unlock(&pCond->m_Lock);
341     if ( nRet != 0 )
342     {
343         OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n",
344                   nRet, strerror(nRet));
345     }
346 
347 	return State;
348 }
349 
350 
351