Home | History | Annotate | Download | only in cups
      1 /*
      2  * Threading primitives for CUPS.
      3  *
      4  * Copyright 2009-2017 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  * '_cupsThreadDetach()' - Tell the OS that the thread is running independently.
    177  */
    178 
    179 void
    180 _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */
    181 {
    182   pthread_detach(thread);
    183 }
    184 
    185 
    186 /*
    187  * '_cupsThreadWait()' - Wait for a thread to exit.
    188  */
    189 
    190 void *					/* O - Return value */
    191 _cupsThreadWait(_cups_thread_t thread)	/* I - Thread ID */
    192 {
    193   void	*ret;				/* Return value */
    194 
    195 
    196   if (pthread_join(thread, &ret))
    197     return (NULL);
    198   else
    199     return (ret);
    200 }
    201 
    202 
    203 #elif defined(WIN32)
    204 #  include <process.h>
    205 
    206 
    207 /*
    208  * '_cupsCondBroadcast()' - Wake up waiting threads.
    209  */
    210 
    211 void
    212 _cupsCondBroadcast(_cups_cond_t *cond)	/* I - Condition */
    213 {
    214   // TODO: Implement me
    215 }
    216 
    217 
    218 /*
    219  * '_cupsCondInit()' - Initialize a condition variable.
    220  */
    221 
    222 void
    223 _cupsCondInit(_cups_cond_t *cond)	/* I - Condition */
    224 {
    225   // TODO: Implement me
    226 }
    227 
    228 
    229 /*
    230  * '_cupsCondWait()' - Wait for a condition with optional timeout.
    231  */
    232 
    233 void
    234 _cupsCondWait(_cups_cond_t  *cond,	/* I - Condition */
    235               _cups_mutex_t *mutex,	/* I - Mutex */
    236 	      double        timeout)	/* I - Timeout in seconds (0 or negative for none) */
    237 {
    238   // TODO: Implement me
    239 }
    240 
    241 
    242 /*
    243  * '_cupsMutexInit()' - Initialize a mutex.
    244  */
    245 
    246 void
    247 _cupsMutexInit(_cups_mutex_t *mutex)	/* I - Mutex */
    248 {
    249   InitializeCriticalSection(&mutex->m_criticalSection);
    250   mutex->m_init = 1;
    251 }
    252 
    253 
    254 /*
    255  * '_cupsMutexLock()' - Lock a mutex.
    256  */
    257 
    258 void
    259 _cupsMutexLock(_cups_mutex_t *mutex)	/* I - Mutex */
    260 {
    261   if (!mutex->m_init)
    262   {
    263     _cupsGlobalLock();
    264 
    265     if (!mutex->m_init)
    266     {
    267       InitializeCriticalSection(&mutex->m_criticalSection);
    268       mutex->m_init = 1;
    269     }
    270 
    271     _cupsGlobalUnlock();
    272   }
    273 
    274   EnterCriticalSection(&mutex->m_criticalSection);
    275 }
    276 
    277 
    278 /*
    279  * '_cupsMutexUnlock()' - Unlock a mutex.
    280  */
    281 
    282 void
    283 _cupsMutexUnlock(_cups_mutex_t *mutex)	/* I - Mutex */
    284 {
    285   LeaveCriticalSection(&mutex->m_criticalSection);
    286 }
    287 
    288 
    289 /*
    290  * '_cupsRWInit()' - Initialize a reader/writer lock.
    291  */
    292 
    293 void
    294 _cupsRWInit(_cups_rwlock_t *rwlock)	/* I - Reader/writer lock */
    295 {
    296   _cupsMutexInit((_cups_mutex_t *)rwlock);
    297 }
    298 
    299 
    300 /*
    301  * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading.
    302  */
    303 
    304 void
    305 _cupsRWLockRead(_cups_rwlock_t *rwlock)	/* I - Reader/writer lock */
    306 {
    307   _cupsMutexLock((_cups_mutex_t *)rwlock);
    308 }
    309 
    310 
    311 /*
    312  * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing.
    313  */
    314 
    315 void
    316 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */
    317 {
    318   _cupsMutexLock((_cups_mutex_t *)rwlock);
    319 }
    320 
    321 
    322 /*
    323  * '_cupsRWUnlock()' - Release a reader/writer lock.
    324  */
    325 
    326 void
    327 _cupsRWUnlock(_cups_rwlock_t *rwlock)	/* I - Reader/writer lock */
    328 {
    329   _cupsMutexUnlock((_cups_mutex_t *)rwlock);
    330 }
    331 
    332 
    333 /*
    334  * '_cupsThreadCancel()' - Cancel (kill) a thread.
    335  */
    336 
    337 void
    338 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */
    339 {
    340   // TODO: Implement me
    341 }
    342 
    343 
    344 /*
    345  * '_cupsThreadCreate()' - Create a thread.
    346  */
    347 
    348 _cups_thread_t				/* O - Thread ID */
    349 _cupsThreadCreate(
    350     _cups_thread_func_t func,		/* I - Entry point */
    351     void                *arg)		/* I - Entry point context */
    352 {
    353   return (_beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL));
    354 }
    355 
    356 
    357 /*
    358  * '_cupsThreadDetach()' - Tell the OS that the thread is running independently.
    359  */
    360 
    361 void
    362 _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */
    363 {
    364   // TODO: Implement me
    365   (void)thread;
    366 }
    367 
    368 
    369 /*
    370  * '_cupsThreadWait()' - Wait for a thread to exit.
    371  */
    372 
    373 void *					/* O - Return value */
    374 _cupsThreadWait(_cups_thread_t thread)	/* I - Thread ID */
    375 {
    376   // TODO: Implement me
    377   (void)thread;
    378 
    379   return (NULL);
    380 }
    381 
    382 
    383 #else /* No threading */
    384 /*
    385  * '_cupsCondBroadcast()' - Wake up waiting threads.
    386  */
    387 
    388 void
    389 _cupsCondBroadcast(_cups_cond_t *cond)	/* I - Condition */
    390 {
    391   // TODO: Implement me
    392 }
    393 
    394 
    395 /*
    396  * '_cupsCondInit()' - Initialize a condition variable.
    397  */
    398 
    399 void
    400 _cupsCondInit(_cups_cond_t *cond)	/* I - Condition */
    401 {
    402   // TODO: Implement me
    403 }
    404 
    405 
    406 /*
    407  * '_cupsCondWait()' - Wait for a condition with optional timeout.
    408  */
    409 
    410 void
    411 _cupsCondWait(_cups_cond_t  *cond,	/* I - Condition */
    412               _cups_mutex_t *mutex,	/* I - Mutex */
    413 	      double        timeout)	/* I - Timeout in seconds (0 or negative for none) */
    414 {
    415   // TODO: Implement me
    416 }
    417 
    418 
    419 /*
    420  * '_cupsMutexInit()' - Initialize a mutex.
    421  */
    422 
    423 void
    424 _cupsMutexInit(_cups_mutex_t *mutex)	/* I - Mutex */
    425 {
    426   (void)mutex;
    427 }
    428 
    429 
    430 /*
    431  * '_cupsMutexLock()' - Lock a mutex.
    432  */
    433 
    434 void
    435 _cupsMutexLock(_cups_mutex_t *mutex)	/* I - Mutex */
    436 {
    437   (void)mutex;
    438 }
    439 
    440 
    441 /*
    442  * '_cupsMutexUnlock()' - Unlock a mutex.
    443  */
    444 
    445 void
    446 _cupsMutexUnlock(_cups_mutex_t *mutex)	/* I - Mutex */
    447 {
    448   (void)mutex;
    449 }
    450 
    451 
    452 /*
    453  * '_cupsRWInit()' - Initialize a reader/writer lock.
    454  */
    455 
    456 void
    457 _cupsRWInit(_cups_rwlock_t *rwlock)	/* I - Reader/writer lock */
    458 {
    459   (void)rwlock;
    460 }
    461 
    462 
    463 /*
    464  * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading.
    465  */
    466 
    467 void
    468 _cupsRWLockRead(_cups_rwlock_t *rwlock)	/* I - Reader/writer lock */
    469 {
    470   (void)rwlock;
    471 }
    472 
    473 
    474 /*
    475  * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing.
    476  */
    477 
    478 void
    479 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */
    480 {
    481   (void)rwlock;
    482 }
    483 
    484 
    485 /*
    486  * '_cupsRWUnlock()' - Release a reader/writer lock.
    487  */
    488 
    489 void
    490 _cupsRWUnlock(_cups_rwlock_t *rwlock)	/* I - Reader/writer lock */
    491 {
    492   (void)rwlock;
    493 }
    494 
    495 
    496 /*
    497  * '_cupsThreadCancel()' - Cancel (kill) a thread.
    498  */
    499 
    500 void
    501 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */
    502 {
    503   (void)thread;
    504 }
    505 
    506 
    507 /*
    508  * '_cupsThreadCreate()' - Create a thread.
    509  */
    510 
    511 _cups_thread_t				/* O - Thread ID */
    512 _cupsThreadCreate(
    513     _cups_thread_func_t func,		/* I - Entry point */
    514     void                *arg)		/* I - Entry point context */
    515 {
    516   fputs("DEBUG: CUPS was compiled without threading support, no thread "
    517         "created.\n", stderr);
    518 
    519   (void)func;
    520   (void)arg;
    521 
    522   return (0);
    523 }
    524 
    525 
    526 /*
    527  * '_cupsThreadWait()' - Wait for a thread to exit.
    528  */
    529 
    530 void *					/* O - Return value */
    531 _cupsThreadWait(_cups_thread_t thread)	/* I - Thread ID */
    532 {
    533   (void)thread;
    534 
    535   return (NULL);
    536 }
    537 
    538 #endif /* HAVE_PTHREAD_H */
    539