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