1 /*****************************************************************************/ 2 // Copyright 2002-2019 Adobe Systems Incorporated 3 // All Rights Reserved. 4 // 5 // NOTICE: Adobe permits you to use, modify, and distribute this file in 6 // accordance with the terms of the Adobe license agreement accompanying it. 7 /*****************************************************************************/ 8 9 #ifndef __dng_pthread__ 10 #define __dng_pthread__ 11 12 /*****************************************************************************/ 13 14 #include "dng_flags.h" 15 16 /*****************************************************************************/ 17 18 #if qDNGThreadSafe 19 20 /*****************************************************************************/ 21 22 //#if !qWinOS 23 #ifndef _MSC_VER 24 25 /*****************************************************************************/ 26 27 /* Try generic POSIX compile */ 28 29 #include <errno.h> 30 #include <pthread.h> 31 32 #define dng_pthread_disassociate() 33 #define dng_pthread_terminate() 34 35 /*****************************************************************************/ 36 37 #else 38 39 /*****************************************************************************/ 40 41 #include <stdlib.h> 42 43 #if _MSC_VER >= 1600 44 45 // Get this included so ETIMEDOUT is predefined. 46 #include <errno.h> 47 48 #endif 49 50 #ifdef __cplusplus 51 extern "C" 52 { 53 #endif 54 55 /*****************************************************************************/ 56 57 #define DNG_ETIMEDOUT 60 /* Operation timed out */ 58 59 struct dng_timespec { 60 long tv_sec; 61 long tv_nsec; 62 }; 63 64 65 typedef unsigned long dng_pthread_t; 66 67 typedef struct dng_pthread_mutex_impl *dng_pthread_mutex_t; 68 typedef struct dng_pthread_cond_impl *dng_pthread_cond_t; 69 typedef unsigned long dng_pthread_key_t; 70 71 72 #define DNG_PTHREAD_MUTEX_INITIALIZER ((struct dng_pthread_mutex_impl *)-1) 73 #define DNG_PTHREAD_COND_INITIALIZER ((struct dng_pthread_cond_impl *)-1) 74 75 struct _dng_pthread_once_t { 76 int inited; 77 long semaphore; 78 }; 79 80 typedef struct _dng_pthread_once_t dng_pthread_once_t; 81 #define DNG_PTHREAD_ONCE_INIT { 0, -1 } 82 83 #define dng_pthread_equal(t1, t2) ((t1) == (t2)) 84 85 typedef struct dng_pthread_attr_impl *dng_pthread_attr_t; 86 87 int dng_pthread_attr_init(dng_pthread_attr_t *attr); 88 int dng_pthread_attr_destroy(dng_pthread_attr_t *attr); 89 90 int dng_pthread_attr_setstacksize(dng_pthread_attr_t *attr, size_t stacksize); 91 int dng_pthread_attr_getstacksize(const dng_pthread_attr_t *attr, size_t *stacksize); 92 93 int dng_pthread_create(dng_pthread_t *thread, const dng_pthread_attr_t * /* attrs */, void * (*func)(void *), void *arg); 94 int dng_pthread_detach(dng_pthread_t thread); 95 int dng_pthread_join(dng_pthread_t thread, void **result); 96 dng_pthread_t dng_pthread_self(); 97 void dng_pthread_exit(void *result); 98 99 #define DNG_PTHREAD_MUTEX_RECURSIVE 0 100 typedef unsigned long dng_pthread_mutexattr_t; 101 102 int dng_pthread_mutexattr_init(dng_pthread_mutexattr_t *mutexattr); 103 int dng_pthread_mutexattr_settype(dng_pthread_mutexattr_t *mutexattr, int /*the options*/); 104 105 int dng_pthread_mutex_init(dng_pthread_mutex_t *mutex, void * /* attrs */); 106 int dng_pthread_mutex_destroy(dng_pthread_mutex_t *mutex); 107 int dng_pthread_mutex_lock(dng_pthread_mutex_t *mutex); 108 int dng_pthread_mutex_unlock(dng_pthread_mutex_t *mutex); 109 110 int dng_pthread_cond_init(dng_pthread_cond_t *cond, void * /* attrs */); 111 int dng_pthread_cond_destroy(dng_pthread_cond_t *cond); 112 int dng_pthread_cond_wait(dng_pthread_cond_t *cond, dng_pthread_mutex_t *mutex); 113 int dng_pthread_cond_timedwait(dng_pthread_cond_t *cond, dng_pthread_mutex_t *mutex, struct dng_timespec *latest_time); 114 int dng_pthread_cond_signal(dng_pthread_cond_t *cond); 115 int dng_pthread_cond_broadcast(dng_pthread_cond_t *cond); 116 117 int dng_pthread_once(dng_pthread_once_t *once, void (*init_func)()); 118 119 int dng_pthread_key_create(dng_pthread_key_t * key, void (*destructor) (void *)); 120 int dng_pthread_key_delete(dng_pthread_key_t key); 121 int dng_pthread_setspecific(dng_pthread_key_t key, const void *value); 122 void *dng_pthread_getspecific(dng_pthread_key_t key); 123 124 typedef struct dng_pthread_rwlock_impl *dng_pthread_rwlock_t; 125 typedef void *pthread_rwlockattr_t; 126 127 int dng_pthread_rwlock_destroy(dng_pthread_rwlock_t * rwlock); 128 int dng_pthread_rwlock_init(dng_pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attrs); 129 int dng_pthread_rwlock_rdlock(dng_pthread_rwlock_t * rwlock); 130 int dng_pthread_rwlock_tryrdlock(dng_pthread_rwlock_t * rwlock); 131 int dng_pthread_rwlock_trywrlock(dng_pthread_rwlock_t * rwlock); 132 int dng_pthread_rwlock_unlock(dng_pthread_rwlock_t * rwlock); 133 int dng_pthread_rwlock_wrlock(dng_pthread_rwlock_t * rwlock); 134 135 // dng_pthread may maintain per-thread global state. This routine frees that global state. 136 // there is no need to call this for threads created by dng_pthread and one can call 137 // dng_pthread routines of a thread after dng_pthread_disassociate as the global state will 138 // be recreated as necessary. However dng_pthread_disassociate will need to be called again 139 // and there is a slight performance cost. Do not call this routine while holding a mutex, etc. 140 void dng_pthread_disassociate(); 141 142 void dng_pthread_terminate(); 143 144 /*****************************************************************************/ 145 146 // Map symbols back to plain pthread names. This whole mechanism is so the DNG pthreads library 147 // symbols do not collide with another pthread emulation library 148 // that may be in use in the same linked entity. However if that is the case, it would be far better 149 // to have the DNG code use the same pthread library as the rest of the code. 150 151 #define pthread_t dng_pthread_t 152 #define pthread_mutex_t dng_pthread_mutex_t 153 #define pthread_cond_t dng_pthread_cond_t 154 #define pthread_once_t dng_pthread_once_t 155 #define pthread_key_t dng_pthread_key_t 156 157 #undef PTHREAD_MUTEX_INITIALIZER 158 #define PTHREAD_MUTEX_INITIALIZER DNG_PTHREAD_MUTEX_INITIALIZER 159 #undef PTHREAD_COND_INITIALIZER 160 #define PTHREAD_COND_INITIALIZER DNG_PTHREAD_COND_INITIALIZER 161 162 #undef PTHREAD_ONCE_INIT 163 #define PTHREAD_ONCE_INIT DNG_PTHREAD_ONCE_INIT 164 165 #if _MSC_VER < 1900 166 #define timespec dng_timespec 167 #endif 168 169 /* If it is defined on Windows, it probably has the wrong value... */ 170 #if defined(WIN32) || !defined(ETIMEDOUT) 171 #undef ETIMEDOUT 172 #define ETIMEDOUT DNG_ETIMEDOUT 173 #endif 174 175 #define pthread_equal dng_pthread_equal 176 177 #define pthread_attr_t dng_pthread_attr_t 178 179 #define pthread_attr_init dng_pthread_attr_init 180 #define pthread_attr_destroy dng_pthread_attr_destroy 181 182 #define pthread_attr_setstacksize dng_pthread_attr_setstacksize 183 #define pthread_attr_getstacksize dng_pthread_attr_getstacksize 184 185 #define pthread_create dng_pthread_create 186 #define pthread_detach dng_pthread_detach 187 #define pthread_join dng_pthread_join 188 #define pthread_self dng_pthread_self 189 #define pthread_exit dng_pthread_exit 190 191 #define pthread_mutex_init dng_pthread_mutex_init 192 #define pthread_mutex_destroy dng_pthread_mutex_destroy 193 #define pthread_mutex_lock dng_pthread_mutex_lock 194 #define pthread_mutex_unlock dng_pthread_mutex_unlock 195 196 #define pthread_cond_init dng_pthread_cond_init 197 #define pthread_cond_destroy dng_pthread_cond_destroy 198 #define pthread_cond_wait dng_pthread_cond_wait 199 #define pthread_cond_timedwait dng_pthread_cond_timedwait 200 #define pthread_cond_signal dng_pthread_cond_signal 201 #define pthread_cond_broadcast dng_pthread_cond_broadcast 202 203 #define pthread_once dng_pthread_once 204 205 #define pthread_key_create dng_pthread_key_create 206 #define pthread_key_delete dng_pthread_key_delete 207 #define pthread_setspecific dng_pthread_setspecific 208 #define pthread_getspecific dng_pthread_getspecific 209 210 #define pthread_rwlock_t dng_pthread_rwlock_t 211 212 #define pthread_rwlock_destroy dng_pthread_rwlock_destroy 213 #define pthread_rwlock_init dng_pthread_rwlock_init 214 #define pthread_rwlock_rdlock dng_pthread_rwlock_rdlock 215 #define pthread_rwlock_tryrdlock dng_pthread_rwlock_tryrdlock 216 #define pthread_rwlock_trywrlock dng_pthread_rwlock_trywrlock 217 #define pthread_rwlock_unlock dng_pthread_rwlock_unlock 218 #define pthread_rwlock_wrlock dng_pthread_rwlock_wrlock 219 220 /*****************************************************************************/ 221 222 #ifdef __cplusplus 223 } 224 #endif 225 226 /*****************************************************************************/ 227 228 #endif 229 230 /*****************************************************************************/ 231 232 #ifdef __cplusplus 233 extern "C" 234 { 235 #endif 236 237 int dng_pthread_now (struct timespec *now); 238 239 #ifdef __cplusplus 240 } 241 #endif 242 243 /*****************************************************************************/ 244 245 #endif // qDNGThreadSafe 246 247 /*****************************************************************************/ 248 249 #endif 250 251 /*****************************************************************************/ 252