1 #ifndef MUPDF_HELPERS_MU_THREADS_H
2 #define MUPDF_HELPERS_MU_THREADS_H
3 
4 /*
5 	Simple threading helper library.
6 	Includes implementations for Windows, pthreads,
7 	and "no threads".
8 
9 	The "no threads" implementation simply provides types
10 	and stub functions so that things will build, but abort
11 	if we try to call them. This simplifies the job for
12 	calling functions.
13 
14 	To build this library on a platform with no threading,
15 	define DISABLE_MUTHREADS (or extend the ifdeffery below
16 	so that it does so).
17 
18 	To build this library on a platform that uses a
19 	threading model other than windows threads or pthreads,
20 	extend the #ifdeffery below to set MUTHREAD_IMPL_TYPE
21 	to an unused value, and modify mu-threads.c
22 	appropriately.
23 */
24 
25 #if !defined(DISABLE_MUTHREADS)
26 #ifdef _WIN32
27 #define MU_THREAD_IMPL_TYPE 1
28 #elif defined(HAVE_PTHREAD)
29 #define MU_THREAD_IMPL_TYPE 2
30 #else
31 #define DISABLE_MUTHREADS
32 #endif
33 #endif
34 
35 /*
36 	Types
37 */
38 typedef struct mu_thread mu_thread;
39 typedef struct mu_semaphore mu_semaphore;
40 typedef struct mu_mutex mu_mutex;
41 
42 /*
43 	Semaphores
44 
45 	Created with a value of 0. Triggering a semaphore
46 	increments the value. Waiting on a semaphore reduces
47 	the value, blocking if it would become negative.
48 
49 	Never increment the value of a semaphore above 1, as
50 	this has undefined meaning in this implementation.
51 */
52 
53 /*
54 	Create a semaphore.
55 
56 	sem: Pointer to a mu_semaphore to populate.
57 
58 	Returns non-zero for error.
59 */
60 int mu_create_semaphore(mu_semaphore *sem);
61 
62 /*
63 	Destroy a semaphore.
64 	Semaphores may safely be destroyed multiple
65 	times. Any semaphore initialised to zeros is
66 	safe to destroy.
67 
68 	Never destroy a semaphore that may be being waited
69 	upon, as this has undefined meaning in this
70 	implementation.
71 
72 	sem: Pointer to a mu_semaphore to destroy.
73 */
74 void mu_destroy_semaphore(mu_semaphore *sem);
75 
76 /*
77 	Increment the value of the
78 	semaphore. Never blocks.
79 
80 	sem: The semaphore to increment.
81 
82 	Returns non-zero on error.
83 */
84 int mu_trigger_semaphore(mu_semaphore *sem);
85 
86 /*
87 	Decrement the value of the
88 	semaphore, blocking if this would involve making
89 	the value negative.
90 
91 	sem: The semaphore to decrement.
92 
93 	Returns non-zero on error.
94 */
95 int mu_wait_semaphore(mu_semaphore *sem);
96 
97 /*
98 	Threads
99 */
100 
101 /*
102 	The type for the function that a thread runs.
103 
104 	arg: User supplied data.
105 */
106 typedef void (mu_thread_fn)(void *arg);
107 
108 /*
109 	Create a thread to run the
110 	supplied function with the supplied argument.
111 
112 	th: Pointer to mu_thread to populate with created
113 	threads information.
114 
115 	fn: The function for the thread to run.
116 
117 	arg: The argument to pass to fn.
118 */
119 int mu_create_thread(mu_thread *th, mu_thread_fn *fn, void *arg);
120 
121 /*
122 	Destroy a thread. This function
123 	blocks until a thread has terminated normally, and
124 	destroys its storage. A mu_thread may safely be destroyed
125 	multiple times, as may any mu_thread initialised with
126 	zeros.
127 
128 	th: Pointer to mu_thread to destroy.
129 */
130 void mu_destroy_thread(mu_thread *th);
131 
132 /*
133 	Mutexes
134 
135 	This implementation does not specify whether
136 	mutexes are recursive or not.
137 */
138 
139 /*
140 	Create a mutex.
141 
142 	mutex: pointer to a mu_mutex to populate.
143 
144 	Returns non-zero on error.
145 */
146 int mu_create_mutex(mu_mutex *mutex);
147 
148 /*
149 	Destroy a mutex. A mu_mutex may
150 	safely be destroyed several times, as may a mu_mutex
151 	initialised with zeros. Never destroy locked mu_mutex.
152 
153 	mutex: Pointer to mu_mutex to destroy.
154 */
155 void mu_destroy_mutex(mu_mutex *mutex);
156 
157 /*
158 	Lock a mutex.
159 
160 	mutex: Mutex to lock.
161 */
162 void mu_lock_mutex(mu_mutex *mutex);
163 
164 /*
165 	Unlock a mutex.
166 
167 	mutex: Mutex to unlock.
168 */
169 void mu_unlock_mutex(mu_mutex *mutex);
170 
171 /*
172 	Everything under this point is implementation specific.
173 	Only people looking to extend the capabilities of this
174 	helper module should need to look below here.
175 */
176 
177 #ifdef DISABLE_MUTHREADS
178 
179 /* Null implementation */
180 struct mu_semaphore
181 {
182 	int dummy;
183 };
184 
185 struct mu_thread
186 {
187 	int dummy;
188 };
189 
190 struct mu_mutex
191 {
192 	int dummy;
193 };
194 
195 #elif MU_THREAD_IMPL_TYPE == 1
196 
197 #include <windows.h>
198 
199 /* Windows threads */
200 struct mu_semaphore
201 {
202 	HANDLE handle;
203 };
204 
205 struct mu_thread
206 {
207 	HANDLE handle;
208 	mu_thread_fn *fn;
209 	void *arg;
210 };
211 
212 struct mu_mutex
213 {
214 	CRITICAL_SECTION mutex;
215 };
216 
217 #elif MU_THREAD_IMPL_TYPE == 2
218 
219 /*
220 	PThreads - without working unnamed semaphores.
221 
222 	Neither ios nor OSX supports unnamed semaphores.
223 	Named semaphores are a pain to use, so we implement
224 	our own semaphores using condition variables and
225 	mutexes.
226 */
227 
228 #include <pthread.h>
229 
230 struct mu_semaphore
231 {
232 	int count;
233 	pthread_mutex_t mutex;
234 	pthread_cond_t cond;
235 };
236 
237 struct mu_thread
238 {
239 	pthread_t thread;
240 	mu_thread_fn *fn;
241 	void *arg;
242 };
243 
244 struct mu_mutex
245 {
246 	pthread_mutex_t mutex;
247 };
248 
249 /*
250 	Add new threading implementations here, with
251 	#elif MU_THREAD_IMPL_TYPE == 3... etc.
252 */
253 
254 #else
255 #error Unknown MU_THREAD_IMPL_TYPE setting
256 #endif
257 
258 #endif /* MUPDF_HELPERS_MU_THREADS_H */
259