Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "sal/config.h"
21 :
22 : #include <assert.h>
23 :
24 : #include "system.h"
25 : #include <sal/log.hxx>
26 : #include <sal/types.h>
27 :
28 : #include <osl/conditn.h>
29 : #include <osl/time.h>
30 :
31 : typedef struct _oslConditionImpl
32 : {
33 : pthread_cond_t m_Condition;
34 : pthread_mutex_t m_Lock;
35 : bool m_State;
36 : } oslConditionImpl;
37 :
38 170027 : oslCondition SAL_CALL osl_createCondition()
39 : {
40 : oslConditionImpl* pCond;
41 170027 : int nRet=0;
42 :
43 170027 : pCond = (oslConditionImpl*) malloc(sizeof(oslConditionImpl));
44 :
45 170027 : if ( pCond == 0 )
46 : {
47 : SAL_WARN("sal.osl", "std::bad_alloc in C");
48 0 : return 0;
49 : }
50 :
51 170027 : pCond->m_State = false;
52 :
53 : /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */
54 170027 : nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT);
55 170027 : if ( nRet != 0 )
56 : {
57 : SAL_WARN(
58 : "sal.osl",
59 : "pthread_cond_init failed, errno " << nRet << ", \""
60 : << strerror(nRet) << '"');
61 :
62 0 : free(pCond);
63 0 : return 0;
64 : }
65 :
66 170027 : nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT);
67 170027 : if ( nRet != 0 )
68 : {
69 : SAL_WARN(
70 : "sal.osl",
71 : "pthread_mutex_init failed, errno " << nRet << ", \""
72 : << strerror(nRet) << '"');
73 :
74 0 : nRet = pthread_cond_destroy(&pCond->m_Condition);
75 : SAL_WARN_IF(
76 : nRet != 0, "sal.osl",
77 : "pthread_cond_destroy failed, errno " << nRet << ", \""
78 : << strerror(nRet) << '"');
79 :
80 0 : free(pCond);
81 0 : pCond = 0;
82 : }
83 :
84 170027 : return (oslCondition)pCond;
85 : }
86 :
87 170027 : void SAL_CALL osl_destroyCondition(oslCondition Condition)
88 : {
89 : oslConditionImpl* pCond;
90 170027 : int nRet = 0;
91 :
92 170027 : if ( Condition )
93 : {
94 170027 : pCond = (oslConditionImpl*)Condition;
95 :
96 170027 : nRet = pthread_cond_destroy(&pCond->m_Condition);
97 : SAL_WARN_IF(
98 : nRet != 0, "sal.osl",
99 : "pthread_cond_destroy failed, errno " << nRet << ", \""
100 : << strerror(nRet) << '"');
101 170027 : nRet = pthread_mutex_destroy(&pCond->m_Lock);
102 : SAL_WARN_IF(
103 : nRet != 0, "sal.osl",
104 : "pthread_mutex_destroy failed, errno " << nRet << ", \""
105 : << strerror(nRet) << '"');
106 :
107 170027 : free(Condition);
108 : }
109 :
110 170027 : return;
111 : }
112 :
113 129209 : sal_Bool SAL_CALL osl_setCondition(oslCondition Condition)
114 : {
115 : oslConditionImpl* pCond;
116 129209 : int nRet=0;
117 :
118 : assert(Condition);
119 129209 : pCond = (oslConditionImpl*)Condition;
120 :
121 129209 : if ( pCond == 0 )
122 : {
123 0 : return sal_False;
124 : }
125 :
126 129209 : nRet = pthread_mutex_lock(&pCond->m_Lock);
127 129209 : if ( nRet != 0 )
128 : {
129 : SAL_WARN(
130 : "sal.osl",
131 : "pthread_mutex_lock failed, errno " << nRet << ", \""
132 : << strerror(nRet) << '"');
133 0 : return sal_False;
134 : }
135 :
136 129209 : pCond->m_State = true;
137 129209 : nRet = pthread_cond_broadcast(&pCond->m_Condition);
138 129209 : if ( nRet != 0 )
139 : {
140 : SAL_WARN(
141 : "sal.osl",
142 : "pthread_cond_broadcast failed, errno " << nRet << ", \""
143 : << strerror(nRet) << '"');
144 : // try to unlock the mutex
145 0 : pthread_mutex_unlock(&pCond->m_Lock);
146 0 : return sal_False;
147 : }
148 :
149 129209 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
150 129209 : if ( nRet != 0 )
151 : {
152 : SAL_WARN(
153 : "sal.osl",
154 : "pthread_mutex_unlock failed, errno " << nRet << ", \""
155 : << strerror(nRet) << '"');
156 0 : return sal_False;
157 : }
158 :
159 129209 : return sal_True;
160 :
161 : }
162 :
163 0 : sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition)
164 : {
165 : oslConditionImpl* pCond;
166 0 : int nRet=0;
167 :
168 : assert(Condition);
169 :
170 0 : pCond = (oslConditionImpl*)Condition;
171 :
172 0 : if ( pCond == 0 )
173 : {
174 0 : return sal_False;
175 : }
176 :
177 0 : nRet = pthread_mutex_lock(&pCond->m_Lock);
178 0 : if ( nRet != 0 )
179 : {
180 : SAL_WARN(
181 : "sal.osl",
182 : "pthread_mutex_lock failed, errno " << nRet << ", \""
183 : << strerror(nRet) << '"');
184 0 : return sal_False;
185 : }
186 :
187 0 : pCond->m_State = false;
188 :
189 0 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
190 0 : if ( nRet != 0 )
191 : {
192 : SAL_WARN(
193 : "sal.osl", "pthread_mutex_unlock failed, errno " << nRet <<", \""
194 : << strerror(nRet) << '"');
195 0 : return sal_False;
196 : }
197 :
198 0 : return sal_True;
199 : }
200 :
201 127520 : oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout)
202 : {
203 : oslConditionImpl* pCond;
204 127520 : int nRet=0;
205 127520 : oslConditionResult Result = osl_cond_result_ok;
206 :
207 : assert(Condition);
208 127520 : pCond = (oslConditionImpl*)Condition;
209 :
210 127520 : if ( pCond == 0 )
211 : {
212 0 : return osl_cond_result_error;
213 : }
214 :
215 127520 : nRet = pthread_mutex_lock(&pCond->m_Lock);
216 127520 : if ( nRet != 0 )
217 : {
218 : SAL_WARN(
219 : "sal.osl", "pthread_mutex_lock failed, errno " << nRet <<", \""
220 : << strerror(nRet) << '"');
221 0 : return osl_cond_result_error;
222 : }
223 :
224 127520 : if ( pTimeout )
225 : {
226 42508 : if ( ! pCond->m_State )
227 : {
228 : int ret;
229 : struct timeval tp;
230 : struct timespec to;
231 :
232 42507 : gettimeofday(&tp, NULL);
233 :
234 42507 : SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds,
235 : tp.tv_usec * 1000 + pTimeout->Nanosec );
236 :
237 : /* spurious wake up prevention */
238 42506 : do
239 : {
240 42507 : ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to);
241 42507 : if ( ret != 0 )
242 : {
243 1 : if ( ret == ETIME || ret == ETIMEDOUT )
244 : {
245 1 : Result = osl_cond_result_timeout;
246 1 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
247 : SAL_WARN_IF(
248 : nRet != 0, "sal.osl",
249 : "pthread_mutex_unlock failed, errno " << nRet
250 : << ", \"" << strerror(nRet) << '"');
251 :
252 2 : return Result;
253 : }
254 0 : else if ( ret != EINTR )
255 : {
256 0 : Result = osl_cond_result_error;
257 0 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
258 : SAL_WARN_IF(
259 : nRet != 0, "sal.osl",
260 : "pthread_mutex_unlock failed, errno " << nRet
261 : << ", \"" << strerror(nRet) << '"');
262 0 : return Result;
263 : }
264 : }
265 : }
266 42506 : while ( !pCond->m_State );
267 : }
268 : }
269 : else
270 : {
271 255002 : while ( !pCond->m_State )
272 : {
273 84978 : nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock);
274 84978 : if ( nRet != 0 )
275 : {
276 : SAL_WARN(
277 : "sal.osl",
278 : "pthread_cond_wait failed, errno " << nRet << ", \""
279 : << strerror(nRet) << '"');
280 0 : Result = osl_cond_result_error;
281 0 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
282 : SAL_WARN_IF(
283 : nRet != 0, "sal.osl",
284 : "pthread_mutex_unlock failed, errno " << nRet << ", \""
285 : << strerror(nRet) << '"');
286 :
287 0 : return Result;
288 : }
289 : }
290 : }
291 :
292 127519 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
293 : SAL_WARN_IF(
294 : nRet != 0, "sal.osl",
295 : "pthread_mutex_unlock failed, errno " << nRet << ", \""
296 : << strerror(nRet) << '"');
297 :
298 127519 : return Result;
299 : }
300 :
301 42505 : sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition)
302 : {
303 : bool State;
304 : oslConditionImpl* pCond;
305 42505 : int nRet=0;
306 :
307 : assert(Condition);
308 42505 : pCond = (oslConditionImpl*)Condition;
309 :
310 42505 : if ( pCond == 0 )
311 : {
312 0 : return sal_False;
313 : }
314 :
315 42505 : nRet = pthread_mutex_lock(&pCond->m_Lock);
316 : SAL_WARN_IF(
317 : nRet != 0, "sal.osl",
318 : "pthread_mutex_lock failed, errno " << nRet << ", \"" << strerror(nRet)
319 : << '"');
320 :
321 42505 : State = pCond->m_State;
322 :
323 42505 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
324 : SAL_WARN_IF(
325 : nRet != 0, "sal.osl",
326 : "pthread_mutex_unlock failed, errno " << nRet << ", \""
327 : << strerror(nRet) << '"');
328 :
329 42505 : return State;
330 : }
331 :
332 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|