1 /* 2 * Threading primitives for CUPS. 3 * 4 * Copyright 2009-2016 by Apple Inc. 5 * 6 * These coded instructions, statements, and computer programs are the 7 * property of Apple Inc. and are protected by Federal copyright 8 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 9 * which should have been included with this file. If this file is 10 * missing or damaged, see the license at "http://www.cups.org/". 11 * 12 * This file is subject to the Apple OS-Developed Software exception. 13 */ 14 15 /* 16 * Include necessary headers... 17 */ 18 19 #include "cups-private.h" 20 #include "thread-private.h" 21 22 23 #if defined(HAVE_PTHREAD_H) 24 /* 25 * '_cupsCondBroadcast()' - Wake up waiting threads. 26 */ 27 28 void 29 _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */ 30 { 31 pthread_cond_broadcast(cond); 32 } 33 34 35 /* 36 * '_cupsCondInit()' - Initialize a condition variable. 37 */ 38 39 void 40 _cupsCondInit(_cups_cond_t *cond) /* I - Condition */ 41 { 42 pthread_cond_init(cond, NULL); 43 } 44 45 46 /* 47 * '_cupsCondWait()' - Wait for a condition with optional timeout. 48 */ 49 50 void 51 _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ 52 _cups_mutex_t *mutex, /* I - Mutex */ 53 double timeout) /* I - Timeout in seconds (0 or negative for none) */ 54 { 55 if (timeout > 0.0) 56 { 57 struct timespec abstime; /* Timeout */ 58 59 abstime.tv_sec = (long)timeout; 60 abstime.tv_nsec = (long)(1000000000 * (timeout - (long)timeout)); 61 62 pthread_cond_timedwait(cond, mutex, &abstime); 63 } 64 else 65 pthread_cond_wait(cond, mutex); 66 } 67 68 69 /* 70 * '_cupsMutexInit()' - Initialize a mutex. 71 */ 72 73 void 74 _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */ 75 { 76 pthread_mutex_init(mutex, NULL); 77 } 78 79 80 /* 81 * '_cupsMutexLock()' - Lock a mutex. 82 */ 83 84 void 85 _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */ 86 { 87 pthread_mutex_lock(mutex); 88 } 89 90 91 /* 92 * '_cupsMutexUnlock()' - Unlock a mutex. 93 */ 94 95 void 96 _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */ 97 { 98 pthread_mutex_unlock(mutex); 99 } 100 101 102 /* 103 * '_cupsRWInit()' - Initialize a reader/writer lock. 104 */ 105 106 void 107 _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 108 { 109 pthread_rwlock_init(rwlock, NULL); 110 } 111 112 113 /* 114 * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading. 115 */ 116 117 void 118 _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 119 { 120 pthread_rwlock_rdlock(rwlock); 121 } 122 123 124 /* 125 * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing. 126 */ 127 128 void 129 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */ 130 { 131 pthread_rwlock_wrlock(rwlock); 132 } 133 134 135 /* 136 * '_cupsRWUnlock()' - Release a reader/writer lock. 137 */ 138 139 void 140 _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 141 { 142 pthread_rwlock_unlock(rwlock); 143 } 144 145 146 /* 147 * '_cupsThreadCancel()' - Cancel (kill) a thread. 148 */ 149 150 void 151 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */ 152 { 153 pthread_cancel(thread); 154 } 155 156 157 /* 158 * '_cupsThreadCreate()' - Create a thread. 159 */ 160 161 _cups_thread_t /* O - Thread ID */ 162 _cupsThreadCreate( 163 _cups_thread_func_t func, /* I - Entry point */ 164 void *arg) /* I - Entry point context */ 165 { 166 pthread_t thread; 167 168 if (pthread_create(&thread, NULL, (void *(*)(void *))func, arg)) 169 return (0); 170 else 171 return (thread); 172 } 173 174 175 /* 176 * '_cupsThreadWait()' - Wait for a thread to exit. 177 */ 178 179 void * /* O - Return value */ 180 _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ 181 { 182 void *ret; /* Return value */ 183 184 185 if (pthread_join(thread, &ret)) 186 return (NULL); 187 else 188 return (ret); 189 } 190 191 192 #elif defined(WIN32) 193 # include <process.h> 194 195 196 /* 197 * '_cupsCondBroadcast()' - Wake up waiting threads. 198 */ 199 200 void 201 _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */ 202 { 203 // TODO: Implement me 204 } 205 206 207 /* 208 * '_cupsCondInit()' - Initialize a condition variable. 209 */ 210 211 void 212 _cupsCondInit(_cups_cond_t *cond) /* I - Condition */ 213 { 214 // TODO: Implement me 215 } 216 217 218 /* 219 * '_cupsCondWait()' - Wait for a condition with optional timeout. 220 */ 221 222 void 223 _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ 224 _cups_mutex_t *mutex, /* I - Mutex */ 225 double timeout) /* I - Timeout in seconds (0 or negative for none) */ 226 { 227 // TODO: Implement me 228 } 229 230 231 /* 232 * '_cupsMutexInit()' - Initialize a mutex. 233 */ 234 235 void 236 _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */ 237 { 238 InitializeCriticalSection(&mutex->m_criticalSection); 239 mutex->m_init = 1; 240 } 241 242 243 /* 244 * '_cupsMutexLock()' - Lock a mutex. 245 */ 246 247 void 248 _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */ 249 { 250 if (!mutex->m_init) 251 { 252 _cupsGlobalLock(); 253 254 if (!mutex->m_init) 255 { 256 InitializeCriticalSection(&mutex->m_criticalSection); 257 mutex->m_init = 1; 258 } 259 260 _cupsGlobalUnlock(); 261 } 262 263 EnterCriticalSection(&mutex->m_criticalSection); 264 } 265 266 267 /* 268 * '_cupsMutexUnlock()' - Unlock a mutex. 269 */ 270 271 void 272 _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */ 273 { 274 LeaveCriticalSection(&mutex->m_criticalSection); 275 } 276 277 278 /* 279 * '_cupsRWInit()' - Initialize a reader/writer lock. 280 */ 281 282 void 283 _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 284 { 285 _cupsMutexInit((_cups_mutex_t *)rwlock); 286 } 287 288 289 /* 290 * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading. 291 */ 292 293 void 294 _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 295 { 296 _cupsMutexLock((_cups_mutex_t *)rwlock); 297 } 298 299 300 /* 301 * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing. 302 */ 303 304 void 305 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */ 306 { 307 _cupsMutexLock((_cups_mutex_t *)rwlock); 308 } 309 310 311 /* 312 * '_cupsRWUnlock()' - Release a reader/writer lock. 313 */ 314 315 void 316 _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 317 { 318 _cupsMutexUnlock((_cups_mutex_t *)rwlock); 319 } 320 321 322 /* 323 * '_cupsThreadCancel()' - Cancel (kill) a thread. 324 */ 325 326 void 327 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */ 328 { 329 // TODO: Implement me 330 } 331 332 333 /* 334 * '_cupsThreadCreate()' - Create a thread. 335 */ 336 337 _cups_thread_t /* O - Thread ID */ 338 _cupsThreadCreate( 339 _cups_thread_func_t func, /* I - Entry point */ 340 void *arg) /* I - Entry point context */ 341 { 342 return (_beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL)); 343 } 344 345 346 /* 347 * '_cupsThreadWait()' - Wait for a thread to exit. 348 */ 349 350 void * /* O - Return value */ 351 _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ 352 { 353 // TODO: Implement me 354 (void)thread; 355 356 return (NULL); 357 } 358 359 360 #else /* No threading */ 361 /* 362 * '_cupsCondBroadcast()' - Wake up waiting threads. 363 */ 364 365 void 366 _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */ 367 { 368 // TODO: Implement me 369 } 370 371 372 /* 373 * '_cupsCondInit()' - Initialize a condition variable. 374 */ 375 376 void 377 _cupsCondInit(_cups_cond_t *cond) /* I - Condition */ 378 { 379 // TODO: Implement me 380 } 381 382 383 /* 384 * '_cupsCondWait()' - Wait for a condition with optional timeout. 385 */ 386 387 void 388 _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ 389 _cups_mutex_t *mutex, /* I - Mutex */ 390 double timeout) /* I - Timeout in seconds (0 or negative for none) */ 391 { 392 // TODO: Implement me 393 } 394 395 396 /* 397 * '_cupsMutexInit()' - Initialize a mutex. 398 */ 399 400 void 401 _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */ 402 { 403 (void)mutex; 404 } 405 406 407 /* 408 * '_cupsMutexLock()' - Lock a mutex. 409 */ 410 411 void 412 _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */ 413 { 414 (void)mutex; 415 } 416 417 418 /* 419 * '_cupsMutexUnlock()' - Unlock a mutex. 420 */ 421 422 void 423 _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */ 424 { 425 (void)mutex; 426 } 427 428 429 /* 430 * '_cupsRWInit()' - Initialize a reader/writer lock. 431 */ 432 433 void 434 _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 435 { 436 (void)rwlock; 437 } 438 439 440 /* 441 * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading. 442 */ 443 444 void 445 _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 446 { 447 (void)rwlock; 448 } 449 450 451 /* 452 * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing. 453 */ 454 455 void 456 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */ 457 { 458 (void)rwlock; 459 } 460 461 462 /* 463 * '_cupsRWUnlock()' - Release a reader/writer lock. 464 */ 465 466 void 467 _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ 468 { 469 (void)rwlock; 470 } 471 472 473 /* 474 * '_cupsThreadCancel()' - Cancel (kill) a thread. 475 */ 476 477 void 478 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */ 479 { 480 (void)thread; 481 } 482 483 484 /* 485 * '_cupsThreadCreate()' - Create a thread. 486 */ 487 488 _cups_thread_t /* O - Thread ID */ 489 _cupsThreadCreate( 490 _cups_thread_func_t func, /* I - Entry point */ 491 void *arg) /* I - Entry point context */ 492 { 493 fputs("DEBUG: CUPS was compiled without threading support, no thread " 494 "created.\n", stderr); 495 496 (void)func; 497 (void)arg; 498 499 return (0); 500 } 501 502 503 /* 504 * '_cupsThreadWait()' - Wait for a thread to exit. 505 */ 506 507 void * /* O - Return value */ 508 _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ 509 { 510 (void)thread; 511 512 return (NULL); 513 } 514 515 #endif /* HAVE_PTHREAD_H */ 516