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 /*****************************************************************************/ 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 == NULL ) 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 = NULL; 86 } 87 88 return (oslCondition)pCond; 89 } 90 91 /*****************************************************************************/ 92 /* osl_destroyCondition */ 93 /*****************************************************************************/ 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 /*****************************************************************************/ 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 == NULL ) 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 (void)pthread_mutex_unlock(&pCond->m_Lock); 153 return sal_False; 154 } 155 156 nRet = pthread_mutex_unlock(&pCond->m_Lock); 157 if ( nRet != 0 ) 158 { 159 OSL_TRACE("osl_setCondition : mutex unlock failed. Errno: %d; %s\n", 160 nRet, strerror(nRet)); 161 return sal_False; 162 } 163 164 return sal_True; 165 166 } 167 168 /*****************************************************************************/ 169 /* osl_resetCondition */ 170 /*****************************************************************************/ 171 sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition) 172 { 173 oslConditionImpl* pCond; 174 int nRet=0; 175 176 OSL_ASSERT(Condition); 177 178 pCond = (oslConditionImpl*)Condition; 179 180 if ( pCond == NULL ) 181 { 182 return sal_False; 183 } 184 185 nRet = pthread_mutex_lock(&pCond->m_Lock); 186 if ( nRet != 0 ) 187 { 188 OSL_TRACE("osl_resetCondition : mutex lock failed. Errno: %d; %s\n", 189 nRet, strerror(nRet)); 190 return sal_False; 191 } 192 193 pCond->m_State = sal_False; 194 195 nRet = pthread_mutex_unlock(&pCond->m_Lock); 196 if ( nRet != 0 ) 197 { 198 OSL_TRACE("osl_resetCondition : mutex unlock failed. Errno: %d; %s\n", 199 nRet, strerror(nRet)); 200 return sal_False; 201 } 202 203 return sal_True; 204 } 205 206 /*****************************************************************************/ 207 /* osl_waitCondition */ 208 /*****************************************************************************/ 209 oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout) 210 { 211 oslConditionImpl* pCond; 212 int nRet=0; 213 oslConditionResult Result = osl_cond_result_ok; 214 215 OSL_ASSERT(Condition); 216 pCond = (oslConditionImpl*)Condition; 217 218 if ( pCond == NULL ) 219 { 220 return osl_cond_result_error; 221 } 222 223 nRet = pthread_mutex_lock(&pCond->m_Lock); 224 if ( nRet != 0 ) 225 { 226 OSL_TRACE("osl_waitCondition : mutex lock failed. Errno: %d; %s\n", 227 nRet, strerror(nRet)); 228 return osl_cond_result_error; 229 } 230 231 if ( pTimeout ) 232 { 233 if ( ! pCond->m_State ) 234 { 235 int ret; 236 struct timeval tp; 237 struct timespec to; 238 239 gettimeofday(&tp, NULL); 240 241 SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds, 242 tp.tv_usec * 1000 + pTimeout->Nanosec ); 243 244 /* spurious wake up prevention */ 245 do 246 { 247 ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to); 248 if ( ret != 0 ) 249 { 250 if ( ret == ETIME || ret == ETIMEDOUT ) 251 { 252 Result = osl_cond_result_timeout; 253 nRet = pthread_mutex_unlock(&pCond->m_Lock); 254 if (nRet != 0) 255 { 256 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n", 257 nRet, strerror(nRet)); 258 } 259 260 return Result; 261 } 262 else if ( ret != EINTR ) 263 { 264 Result = osl_cond_result_error; 265 nRet = pthread_mutex_unlock(&pCond->m_Lock); 266 if ( nRet != 0 ) 267 { 268 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n", 269 nRet, strerror(nRet)); 270 } 271 return Result; 272 } 273 /* OSL_TRACE("EINTR\n");*/ 274 } 275 } 276 while ( !pCond->m_State ); 277 } 278 } 279 else 280 { 281 while ( !pCond->m_State ) 282 { 283 nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock); 284 if ( nRet != 0 ) 285 { 286 OSL_TRACE("osl_waitCondition : condition wait failed. Errno: %d; %s\n", 287 nRet, strerror(nRet)); 288 Result = osl_cond_result_error; 289 nRet = pthread_mutex_unlock(&pCond->m_Lock); 290 if ( nRet != 0 ) 291 { 292 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n", 293 nRet, strerror(nRet)); 294 } 295 296 return Result; 297 } 298 } 299 } 300 301 nRet = pthread_mutex_unlock(&pCond->m_Lock); 302 if ( nRet != 0 ) 303 { 304 OSL_TRACE("osl_waitCondition : mutex unlock failed. Errno: %d; %s\n", 305 nRet, strerror(nRet)); 306 } 307 308 return Result; 309 } 310 311 /*****************************************************************************/ 312 /* osl_checkCondition */ 313 /*****************************************************************************/ 314 sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition) 315 { 316 sal_Bool State; 317 oslConditionImpl* pCond; 318 int nRet=0; 319 320 OSL_ASSERT(Condition); 321 pCond = (oslConditionImpl*)Condition; 322 323 if ( pCond == NULL ) 324 { 325 return sal_False; 326 } 327 328 nRet = pthread_mutex_lock(&pCond->m_Lock); 329 if ( nRet != 0 ) 330 { 331 OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n", 332 nRet, strerror(nRet)); 333 } 334 335 State = pCond->m_State; 336 337 nRet = pthread_mutex_unlock(&pCond->m_Lock); 338 if ( nRet != 0 ) 339 { 340 OSL_TRACE("osl_checkCondition : mutex unlock failed. Errno: %d; %s\n", 341 nRet, strerror(nRet)); 342 } 343 344 return State; 345 } 346 347 348