Home | History | Annotate | Download | only in cups
      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