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