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