| /* | |
| * Threading primitives for CUPS. | |
| * | |
| * Copyright 2009-2017 by Apple Inc. | |
| * | |
| * These coded instructions, statements, and computer programs are the | |
| * property of Apple Inc. and are protected by Federal copyright | |
| * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
| * which should have been included with this file. If this file is | |
| * missing or damaged, see the license at "http://www.cups.org/". | |
| * | |
| * This file is subject to the Apple OS-Developed Software exception. | |
| */ | |
| /* | |
| * Include necessary headers... | |
| */ | |
| #include "cups-private.h" | |
| #include "thread-private.h" | |
| #if defined(HAVE_PTHREAD_H) | |
| /* | |
| * '_cupsCondBroadcast()' - Wake up waiting threads. | |
| */ | |
| void | |
| _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */ | |
| { | |
| pthread_cond_broadcast(cond); | |
| } | |
| /* | |
| * '_cupsCondInit()' - Initialize a condition variable. | |
| */ | |
| void | |
| _cupsCondInit(_cups_cond_t *cond) /* I - Condition */ | |
| { | |
| pthread_cond_init(cond, NULL); | |
| } | |
| /* | |
| * '_cupsCondWait()' - Wait for a condition with optional timeout. | |
| */ | |
| void | |
| _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ | |
| _cups_mutex_t *mutex, /* I - Mutex */ | |
| double timeout) /* I - Timeout in seconds (0 or negative for none) */ | |
| { | |
| if (timeout > 0.0) | |
| { | |
| struct timespec abstime; /* Timeout */ | |
| abstime.tv_sec = (long)timeout; | |
| abstime.tv_nsec = (long)(1000000000 * (timeout - (long)timeout)); | |
| pthread_cond_timedwait(cond, mutex, &abstime); | |
| } | |
| else | |
| pthread_cond_wait(cond, mutex); | |
| } | |
| /* | |
| * '_cupsMutexInit()' - Initialize a mutex. | |
| */ | |
| void | |
| _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| pthread_mutex_init(mutex, NULL); | |
| } | |
| /* | |
| * '_cupsMutexLock()' - Lock a mutex. | |
| */ | |
| void | |
| _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| pthread_mutex_lock(mutex); | |
| } | |
| /* | |
| * '_cupsMutexUnlock()' - Unlock a mutex. | |
| */ | |
| void | |
| _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| pthread_mutex_unlock(mutex); | |
| } | |
| /* | |
| * '_cupsRWInit()' - Initialize a reader/writer lock. | |
| */ | |
| void | |
| _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| pthread_rwlock_init(rwlock, NULL); | |
| } | |
| /* | |
| * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading. | |
| */ | |
| void | |
| _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| pthread_rwlock_rdlock(rwlock); | |
| } | |
| /* | |
| * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing. | |
| */ | |
| void | |
| _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */ | |
| { | |
| pthread_rwlock_wrlock(rwlock); | |
| } | |
| /* | |
| * '_cupsRWUnlock()' - Release a reader/writer lock. | |
| */ | |
| void | |
| _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| pthread_rwlock_unlock(rwlock); | |
| } | |
| /* | |
| * '_cupsThreadCancel()' - Cancel (kill) a thread. | |
| */ | |
| void | |
| _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */ | |
| { | |
| pthread_cancel(thread); | |
| } | |
| /* | |
| * '_cupsThreadCreate()' - Create a thread. | |
| */ | |
| _cups_thread_t /* O - Thread ID */ | |
| _cupsThreadCreate( | |
| _cups_thread_func_t func, /* I - Entry point */ | |
| void *arg) /* I - Entry point context */ | |
| { | |
| pthread_t thread; | |
| if (pthread_create(&thread, NULL, (void *(*)(void *))func, arg)) | |
| return (0); | |
| else | |
| return (thread); | |
| } | |
| /* | |
| * '_cupsThreadDetach()' - Tell the OS that the thread is running independently. | |
| */ | |
| void | |
| _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */ | |
| { | |
| pthread_detach(thread); | |
| } | |
| /* | |
| * '_cupsThreadWait()' - Wait for a thread to exit. | |
| */ | |
| void * /* O - Return value */ | |
| _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ | |
| { | |
| void *ret; /* Return value */ | |
| if (pthread_join(thread, &ret)) | |
| return (NULL); | |
| else | |
| return (ret); | |
| } | |
| #elif defined(WIN32) | |
| # include <process.h> | |
| /* | |
| * '_cupsCondBroadcast()' - Wake up waiting threads. | |
| */ | |
| void | |
| _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsCondInit()' - Initialize a condition variable. | |
| */ | |
| void | |
| _cupsCondInit(_cups_cond_t *cond) /* I - Condition */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsCondWait()' - Wait for a condition with optional timeout. | |
| */ | |
| void | |
| _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ | |
| _cups_mutex_t *mutex, /* I - Mutex */ | |
| double timeout) /* I - Timeout in seconds (0 or negative for none) */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsMutexInit()' - Initialize a mutex. | |
| */ | |
| void | |
| _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| InitializeCriticalSection(&mutex->m_criticalSection); | |
| mutex->m_init = 1; | |
| } | |
| /* | |
| * '_cupsMutexLock()' - Lock a mutex. | |
| */ | |
| void | |
| _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| if (!mutex->m_init) | |
| { | |
| _cupsGlobalLock(); | |
| if (!mutex->m_init) | |
| { | |
| InitializeCriticalSection(&mutex->m_criticalSection); | |
| mutex->m_init = 1; | |
| } | |
| _cupsGlobalUnlock(); | |
| } | |
| EnterCriticalSection(&mutex->m_criticalSection); | |
| } | |
| /* | |
| * '_cupsMutexUnlock()' - Unlock a mutex. | |
| */ | |
| void | |
| _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| LeaveCriticalSection(&mutex->m_criticalSection); | |
| } | |
| /* | |
| * '_cupsRWInit()' - Initialize a reader/writer lock. | |
| */ | |
| void | |
| _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| _cupsMutexInit((_cups_mutex_t *)rwlock); | |
| } | |
| /* | |
| * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading. | |
| */ | |
| void | |
| _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| _cupsMutexLock((_cups_mutex_t *)rwlock); | |
| } | |
| /* | |
| * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing. | |
| */ | |
| void | |
| _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */ | |
| { | |
| _cupsMutexLock((_cups_mutex_t *)rwlock); | |
| } | |
| /* | |
| * '_cupsRWUnlock()' - Release a reader/writer lock. | |
| */ | |
| void | |
| _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| _cupsMutexUnlock((_cups_mutex_t *)rwlock); | |
| } | |
| /* | |
| * '_cupsThreadCancel()' - Cancel (kill) a thread. | |
| */ | |
| void | |
| _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsThreadCreate()' - Create a thread. | |
| */ | |
| _cups_thread_t /* O - Thread ID */ | |
| _cupsThreadCreate( | |
| _cups_thread_func_t func, /* I - Entry point */ | |
| void *arg) /* I - Entry point context */ | |
| { | |
| return (_beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL)); | |
| } | |
| /* | |
| * '_cupsThreadDetach()' - Tell the OS that the thread is running independently. | |
| */ | |
| void | |
| _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */ | |
| { | |
| // TODO: Implement me | |
| (void)thread; | |
| } | |
| /* | |
| * '_cupsThreadWait()' - Wait for a thread to exit. | |
| */ | |
| void * /* O - Return value */ | |
| _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ | |
| { | |
| // TODO: Implement me | |
| (void)thread; | |
| return (NULL); | |
| } | |
| #else /* No threading */ | |
| /* | |
| * '_cupsCondBroadcast()' - Wake up waiting threads. | |
| */ | |
| void | |
| _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsCondInit()' - Initialize a condition variable. | |
| */ | |
| void | |
| _cupsCondInit(_cups_cond_t *cond) /* I - Condition */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsCondWait()' - Wait for a condition with optional timeout. | |
| */ | |
| void | |
| _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ | |
| _cups_mutex_t *mutex, /* I - Mutex */ | |
| double timeout) /* I - Timeout in seconds (0 or negative for none) */ | |
| { | |
| // TODO: Implement me | |
| } | |
| /* | |
| * '_cupsMutexInit()' - Initialize a mutex. | |
| */ | |
| void | |
| _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| (void)mutex; | |
| } | |
| /* | |
| * '_cupsMutexLock()' - Lock a mutex. | |
| */ | |
| void | |
| _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| (void)mutex; | |
| } | |
| /* | |
| * '_cupsMutexUnlock()' - Unlock a mutex. | |
| */ | |
| void | |
| _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */ | |
| { | |
| (void)mutex; | |
| } | |
| /* | |
| * '_cupsRWInit()' - Initialize a reader/writer lock. | |
| */ | |
| void | |
| _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| (void)rwlock; | |
| } | |
| /* | |
| * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading. | |
| */ | |
| void | |
| _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| (void)rwlock; | |
| } | |
| /* | |
| * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing. | |
| */ | |
| void | |
| _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */ | |
| { | |
| (void)rwlock; | |
| } | |
| /* | |
| * '_cupsRWUnlock()' - Release a reader/writer lock. | |
| */ | |
| void | |
| _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */ | |
| { | |
| (void)rwlock; | |
| } | |
| /* | |
| * '_cupsThreadCancel()' - Cancel (kill) a thread. | |
| */ | |
| void | |
| _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */ | |
| { | |
| (void)thread; | |
| } | |
| /* | |
| * '_cupsThreadCreate()' - Create a thread. | |
| */ | |
| _cups_thread_t /* O - Thread ID */ | |
| _cupsThreadCreate( | |
| _cups_thread_func_t func, /* I - Entry point */ | |
| void *arg) /* I - Entry point context */ | |
| { | |
| fputs("DEBUG: CUPS was compiled without threading support, no thread " | |
| "created.\n", stderr); | |
| (void)func; | |
| (void)arg; | |
| return (0); | |
| } | |
| /* | |
| * '_cupsThreadWait()' - Wait for a thread to exit. | |
| */ | |
| void * /* O - Return value */ | |
| _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ | |
| { | |
| (void)thread; | |
| return (NULL); | |
| } | |
| #endif /* HAVE_PTHREAD_H */ |