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 == 0 ) 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 = 0; 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 == 0 ) 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 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 == 0 ) 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 == 0 ) 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 == 0 ) 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 346 347