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 #include "system.h" 25 #include <sal/types.h> 26 27 #include <osl/conditn.h> 28 #include <osl/diagnose.h> 29 #include <osl/time.h> 30 31 32 typedef struct _oslConditionImpl 33 { 34 pthread_cond_t m_Condition; 35 pthread_mutex_t m_Lock; 36 sal_Bool m_State; 37 } oslConditionImpl; 38 39 40 /*****************************************************************************/ 41 /* osl_createCondition */ 42 /*****************************************************************************/ 43 oslCondition SAL_CALL osl_createCondition() 44 { 45 oslConditionImpl* pCond; 46 int nRet=0; 47 48 pCond = (oslConditionImpl*) malloc(sizeof(oslConditionImpl)); 49 50 OSL_ASSERT(pCond); 51 52 if ( pCond == NULL ) 53 { 54 return 0; 55 } 56 57 pCond->m_State = sal_False; 58 59 /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */ 60 nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT); 61 if ( nRet != 0 ) 62 { 63 OSL_TRACE("osl_createCondition : condition init failed. Errno: %d; '%s'\n", 64 nRet, strerror(nRet)); 65 66 free(pCond); 67 return 0; 68 } 69 70 nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT); 71 if ( nRet != 0 ) 72 { 73 OSL_TRACE("osl_createCondition : mutex init failed. Errno: %d; %s\n", 74 nRet, strerror(nRet)); 75 76 nRet = pthread_cond_destroy(&pCond->m_Condition); 77 if ( nRet != 0 ) 78 { 79 OSL_TRACE("osl_createCondition : destroy condition failed. Errno: %d; '%s'\n", 80 nRet, strerror(nRet)); 81 } 82 83 free(pCond); 84 pCond = NULL; 85 } 86 87 return (oslCondition)pCond; 88 } 89 90 /*****************************************************************************/ 91 /* osl_destroyCondition */ 92 /*****************************************************************************/ 93 void SAL_CALL osl_destroyCondition(oslCondition Condition) 94 { 95 oslConditionImpl* pCond; 96 int nRet = 0; 97 98 if ( Condition ) 99 { 100 pCond = (oslConditionImpl*)Condition; 101 102 nRet = pthread_cond_destroy(&pCond->m_Condition); 103 if ( nRet != 0 ) 104 { 105 OSL_TRACE("osl_destroyCondition : destroy condition failed. Errno: %d; '%s'\n", 106 nRet, strerror(nRet)); 107 } 108 nRet = pthread_mutex_destroy(&pCond->m_Lock); 109 if ( nRet != 0 ) 110 { 111 OSL_TRACE("osl_destroyCondition : destroy mutex failed. Errno: %d; '%s'\n", 112 nRet, strerror(nRet)); 113 } 114 115 free(Condition); 116 } 117 118 return; 119 } 120 121 /*****************************************************************************/ 122 /* osl_setCondition */ 123 /*****************************************************************************/ 124 sal_Bool SAL_CALL osl_setCondition(oslCondition Condition) 125 { 126 oslConditionImpl* pCond; 127 int nRet=0; 128 129 OSL_ASSERT(Condition); 130 pCond = (oslConditionImpl*)Condition; 131 132 if ( pCond == NULL ) 133 { 134 return sal_False; 135 } 136 137 nRet = pthread_mutex_lock(&pCond->m_Lock); 138 if ( nRet != 0 ) 139 { 140 OSL_TRACE("osl_setCondition : mutex lock failed. Errno: %d; %s\n", 141 nRet, strerror(nRet)); 142 return sal_False; 143 } 144 145 pCond->m_State = sal_True; 146 nRet = pthread_cond_broadcast(&pCond->m_Condition); 147 if ( nRet != 0 ) 148 { 149 OSL_TRACE("osl_setCondition : condition broadcast failed. Errno: %d; %s\n", 150 nRet, strerror(nRet)); 151 (void)pthread_mutex_unlock(&pCond->m_Lock); 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 /*****************************************************************************/ 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 == NULL ) 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 /*****************************************************************************/ 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 == NULL ) 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 /*****************************************************************************/ 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 == NULL ) 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