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.hxx"
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 663001 : oslCondition SAL_CALL osl_createCondition()
39 : {
40 : oslConditionImpl* pCond;
41 663001 : int nRet=0;
42 :
43 663001 : pCond = static_cast<oslConditionImpl*>(malloc(sizeof(oslConditionImpl)));
44 :
45 663001 : if ( pCond == 0 )
46 : {
47 0 : return 0;
48 : }
49 :
50 663001 : pCond->m_State = false;
51 :
52 : /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */
53 663001 : nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT);
54 663004 : if ( nRet != 0 )
55 : {
56 : SAL_WARN( "sal.osl.condition", "pthread_cond_init failed: " << strerror(nRet) );
57 :
58 0 : free(pCond);
59 0 : return 0;
60 : }
61 :
62 663004 : nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT);
63 663004 : if ( nRet != 0 )
64 : {
65 : SAL_WARN( "sal.osl.condition", "pthread_mutex_init failed: " << strerror(nRet) );
66 :
67 0 : nRet = pthread_cond_destroy(&pCond->m_Condition);
68 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "pthread_cond_destroy failed: " << strerror(nRet) );
69 :
70 0 : free(pCond);
71 0 : pCond = 0;
72 : }
73 :
74 : SAL_INFO( "sal.osl.condition", "osl_createCondition(): " << pCond );
75 :
76 663004 : return static_cast<oslCondition>(pCond);
77 : }
78 :
79 662097 : void SAL_CALL osl_destroyCondition(oslCondition Condition)
80 : {
81 : oslConditionImpl* pCond;
82 :
83 662097 : pCond = static_cast<oslConditionImpl*>(Condition);
84 :
85 : SAL_INFO( "sal.osl.condition", "osl_destroyCondition(" << pCond << ")" );
86 :
87 662097 : if ( pCond )
88 : {
89 662097 : int nRet = pthread_cond_destroy(&pCond->m_Condition);
90 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "pthread_cond_destroy failed: " << strerror(nRet) );
91 662101 : nRet = pthread_mutex_destroy(&pCond->m_Lock);
92 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "pthread_mutex_destroy failed: " << strerror(nRet) );
93 :
94 662101 : free(Condition);
95 : }
96 :
97 662101 : return;
98 : }
99 :
100 3460335 : sal_Bool SAL_CALL osl_setCondition(oslCondition Condition)
101 : {
102 : oslConditionImpl* pCond;
103 3460335 : int nRet=0;
104 :
105 : assert(Condition);
106 3460335 : pCond = static_cast<oslConditionImpl*>(Condition);
107 :
108 3460335 : nRet = pthread_mutex_lock(&pCond->m_Lock);
109 3460324 : if ( nRet != 0 )
110 : {
111 : SAL_WARN( "sal.osl.condition", "osl_setCondition(" << pCond << "): pthread_mutex_lock failed: " << strerror(nRet) );
112 0 : return sal_False;
113 : }
114 :
115 3460324 : pCond->m_State = true;
116 3460324 : nRet = pthread_cond_broadcast(&pCond->m_Condition);
117 3460341 : if ( nRet != 0 )
118 : {
119 : SAL_WARN( "sal.osl.condition", "osl_setCondition(" << pCond << "): pthread_cond_broadcast failed: " << strerror(nRet) );
120 : // try to unlock the mutex
121 0 : pthread_mutex_unlock(&pCond->m_Lock);
122 0 : return sal_False;
123 : }
124 :
125 3460341 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
126 3460341 : if ( nRet != 0 )
127 : {
128 : SAL_WARN( "sal.osl.condition", "osl_setCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
129 0 : return sal_False;
130 : }
131 :
132 : SAL_INFO( "sal.osl.condition", "osl_setCondition(" << pCond << ")" );
133 :
134 3460341 : return sal_True;
135 :
136 : }
137 :
138 3227758 : sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition)
139 : {
140 : oslConditionImpl* pCond;
141 3227758 : int nRet=0;
142 :
143 : assert(Condition);
144 :
145 3227758 : pCond = static_cast<oslConditionImpl*>(Condition);
146 :
147 3227758 : nRet = pthread_mutex_lock(&pCond->m_Lock);
148 3227786 : if ( nRet != 0 )
149 : {
150 : SAL_WARN( "sal.osl.condition", "osl_resetCondition(" << pCond << "): pthread_mutex_lock failed: " << strerror(nRet) );
151 0 : return sal_False;
152 : }
153 :
154 3227796 : pCond->m_State = false;
155 :
156 3227796 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
157 3227796 : if ( nRet != 0 )
158 : {
159 : SAL_WARN( "sal.osl.condition", "osl_resetCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
160 0 : return sal_False;
161 : }
162 :
163 : SAL_INFO( "sal.osl.condition", "osl_resetCondition(" << pCond << ")" );
164 :
165 3227796 : return sal_True;
166 : }
167 :
168 2556766 : oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout)
169 : {
170 : oslConditionImpl* pCond;
171 2556766 : int nRet=0;
172 2556766 : oslConditionResult Result = osl_cond_result_ok;
173 :
174 : assert(Condition);
175 2556766 : pCond = static_cast<oslConditionImpl*>(Condition);
176 :
177 : SAL_INFO( "sal.osl.condition", "osl_waitCondition(" << pCond << ")" );
178 :
179 2556766 : nRet = pthread_mutex_lock(&pCond->m_Lock);
180 2556765 : if ( nRet != 0 )
181 : {
182 : SAL_WARN( "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_lock failed: " << strerror(nRet) );
183 1 : return osl_cond_result_error;
184 : }
185 :
186 2556764 : if ( pTimeout )
187 : {
188 233462 : if ( ! pCond->m_State )
189 : {
190 : struct timeval tp;
191 : struct timespec to;
192 :
193 233438 : gettimeofday(&tp, NULL);
194 :
195 233438 : SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds,
196 : tp.tv_usec * 1000 + pTimeout->Nanosec );
197 :
198 : /* spurious wake up prevention */
199 231576 : do
200 : {
201 233427 : const int ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to);
202 233409 : if ( ret != 0 )
203 : {
204 1833 : if ( ret == ETIME || ret == ETIMEDOUT )
205 : {
206 1833 : Result = osl_cond_result_timeout;
207 1833 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
208 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
209 :
210 3666 : return Result;
211 : }
212 0 : else if ( ret != EINTR )
213 : {
214 0 : Result = osl_cond_result_error;
215 0 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
216 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
217 0 : return Result;
218 : }
219 : }
220 : }
221 231576 : while ( !pCond->m_State );
222 : }
223 : }
224 : else
225 : {
226 6424457 : while ( !pCond->m_State )
227 : {
228 1777873 : nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock);
229 1777853 : if ( nRet != 0 )
230 : {
231 : SAL_WARN( "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_cond_wait failed: " << strerror(nRet) );
232 0 : Result = osl_cond_result_error;
233 0 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
234 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
235 :
236 0 : return Result;
237 : }
238 : }
239 : }
240 :
241 2554893 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
242 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
243 :
244 : SAL_INFO( "sal.osl.condition", "osl_waitCondition(" << pCond << "): " << (Result == osl_cond_result_ok ? "OK" : "ERROR") );
245 :
246 2554933 : return Result;
247 : }
248 :
249 1465372 : sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition)
250 : {
251 : bool State;
252 : oslConditionImpl* pCond;
253 1465372 : int nRet=0;
254 :
255 : assert(Condition);
256 1465372 : pCond = static_cast<oslConditionImpl*>(Condition);
257 :
258 1465372 : nRet = pthread_mutex_lock(&pCond->m_Lock);
259 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_checkCondition(" << pCond << "): pthread_mutex_lock failed: " << strerror(nRet) );
260 :
261 1465372 : State = pCond->m_State;
262 :
263 1465372 : nRet = pthread_mutex_unlock(&pCond->m_Lock);
264 : SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_checkCondition(" << pCond << "): pthread_mutex_unlock failed: " << strerror(nRet) );
265 :
266 : SAL_INFO( "sal.osl.condition", "osl_checkCondition(" << pCond << "): " << (State ? "YES" : "NO") );
267 :
268 1465372 : return State;
269 : }
270 :
271 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|