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