]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/thread.c
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / cups / thread.c
1 /*
2 * Threading primitives for CUPS.
3 *
4 * Copyright 2009-2017 by Apple Inc.
5 *
6 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
7 */
8
9 /*
10 * Include necessary headers...
11 */
12
13 #include "cups-private.h"
14 #include "thread-private.h"
15
16
17 #if defined(HAVE_PTHREAD_H)
18 /*
19 * '_cupsCondBroadcast()' - Wake up waiting threads.
20 */
21
22 void
23 _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */
24 {
25 pthread_cond_broadcast(cond);
26 }
27
28
29 /*
30 * '_cupsCondInit()' - Initialize a condition variable.
31 */
32
33 void
34 _cupsCondInit(_cups_cond_t *cond) /* I - Condition */
35 {
36 pthread_cond_init(cond, NULL);
37 }
38
39
40 /*
41 * '_cupsCondWait()' - Wait for a condition with optional timeout.
42 */
43
44 void
45 _cupsCondWait(_cups_cond_t *cond, /* I - Condition */
46 _cups_mutex_t *mutex, /* I - Mutex */
47 double timeout) /* I - Timeout in seconds (0 or negative for none) */
48 {
49 if (timeout > 0.0)
50 {
51 struct timespec abstime; /* Timeout */
52
53 abstime.tv_sec = (long)timeout;
54 abstime.tv_nsec = (long)(1000000000 * (timeout - (long)timeout));
55
56 pthread_cond_timedwait(cond, mutex, &abstime);
57 }
58 else
59 pthread_cond_wait(cond, mutex);
60 }
61
62
63 /*
64 * '_cupsMutexInit()' - Initialize a mutex.
65 */
66
67 void
68 _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */
69 {
70 pthread_mutex_init(mutex, NULL);
71 }
72
73
74 /*
75 * '_cupsMutexLock()' - Lock a mutex.
76 */
77
78 void
79 _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */
80 {
81 pthread_mutex_lock(mutex);
82 }
83
84
85 /*
86 * '_cupsMutexUnlock()' - Unlock a mutex.
87 */
88
89 void
90 _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
91 {
92 pthread_mutex_unlock(mutex);
93 }
94
95
96 /*
97 * '_cupsRWInit()' - Initialize a reader/writer lock.
98 */
99
100 void
101 _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
102 {
103 pthread_rwlock_init(rwlock, NULL);
104 }
105
106
107 /*
108 * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading.
109 */
110
111 void
112 _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
113 {
114 pthread_rwlock_rdlock(rwlock);
115 }
116
117
118 /*
119 * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing.
120 */
121
122 void
123 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */
124 {
125 pthread_rwlock_wrlock(rwlock);
126 }
127
128
129 /*
130 * '_cupsRWUnlock()' - Release a reader/writer lock.
131 */
132
133 void
134 _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
135 {
136 pthread_rwlock_unlock(rwlock);
137 }
138
139
140 /*
141 * '_cupsThreadCancel()' - Cancel (kill) a thread.
142 */
143
144 void
145 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */
146 {
147 pthread_cancel(thread);
148 }
149
150
151 /*
152 * '_cupsThreadCreate()' - Create a thread.
153 */
154
155 _cups_thread_t /* O - Thread ID */
156 _cupsThreadCreate(
157 _cups_thread_func_t func, /* I - Entry point */
158 void *arg) /* I - Entry point context */
159 {
160 pthread_t thread;
161
162 if (pthread_create(&thread, NULL, (void *(*)(void *))func, arg))
163 return (0);
164 else
165 return (thread);
166 }
167
168
169 /*
170 * '_cupsThreadDetach()' - Tell the OS that the thread is running independently.
171 */
172
173 void
174 _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */
175 {
176 pthread_detach(thread);
177 }
178
179
180 /*
181 * '_cupsThreadWait()' - Wait for a thread to exit.
182 */
183
184 void * /* O - Return value */
185 _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */
186 {
187 void *ret; /* Return value */
188
189
190 if (pthread_join(thread, &ret))
191 return (NULL);
192 else
193 return (ret);
194 }
195
196
197 #elif defined(WIN32)
198 # include <process.h>
199
200
201 /*
202 * '_cupsCondBroadcast()' - Wake up waiting threads.
203 */
204
205 void
206 _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */
207 {
208 // TODO: Implement me
209 }
210
211
212 /*
213 * '_cupsCondInit()' - Initialize a condition variable.
214 */
215
216 void
217 _cupsCondInit(_cups_cond_t *cond) /* I - Condition */
218 {
219 // TODO: Implement me
220 }
221
222
223 /*
224 * '_cupsCondWait()' - Wait for a condition with optional timeout.
225 */
226
227 void
228 _cupsCondWait(_cups_cond_t *cond, /* I - Condition */
229 _cups_mutex_t *mutex, /* I - Mutex */
230 double timeout) /* I - Timeout in seconds (0 or negative for none) */
231 {
232 // TODO: Implement me
233 }
234
235
236 /*
237 * '_cupsMutexInit()' - Initialize a mutex.
238 */
239
240 void
241 _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */
242 {
243 InitializeCriticalSection(&mutex->m_criticalSection);
244 mutex->m_init = 1;
245 }
246
247
248 /*
249 * '_cupsMutexLock()' - Lock a mutex.
250 */
251
252 void
253 _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */
254 {
255 if (!mutex->m_init)
256 {
257 _cupsGlobalLock();
258
259 if (!mutex->m_init)
260 {
261 InitializeCriticalSection(&mutex->m_criticalSection);
262 mutex->m_init = 1;
263 }
264
265 _cupsGlobalUnlock();
266 }
267
268 EnterCriticalSection(&mutex->m_criticalSection);
269 }
270
271
272 /*
273 * '_cupsMutexUnlock()' - Unlock a mutex.
274 */
275
276 void
277 _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
278 {
279 LeaveCriticalSection(&mutex->m_criticalSection);
280 }
281
282
283 /*
284 * '_cupsRWInit()' - Initialize a reader/writer lock.
285 */
286
287 void
288 _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
289 {
290 _cupsMutexInit((_cups_mutex_t *)rwlock);
291 }
292
293
294 /*
295 * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading.
296 */
297
298 void
299 _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
300 {
301 _cupsMutexLock((_cups_mutex_t *)rwlock);
302 }
303
304
305 /*
306 * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing.
307 */
308
309 void
310 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */
311 {
312 _cupsMutexLock((_cups_mutex_t *)rwlock);
313 }
314
315
316 /*
317 * '_cupsRWUnlock()' - Release a reader/writer lock.
318 */
319
320 void
321 _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
322 {
323 _cupsMutexUnlock((_cups_mutex_t *)rwlock);
324 }
325
326
327 /*
328 * '_cupsThreadCancel()' - Cancel (kill) a thread.
329 */
330
331 void
332 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */
333 {
334 // TODO: Implement me
335 }
336
337
338 /*
339 * '_cupsThreadCreate()' - Create a thread.
340 */
341
342 _cups_thread_t /* O - Thread ID */
343 _cupsThreadCreate(
344 _cups_thread_func_t func, /* I - Entry point */
345 void *arg) /* I - Entry point context */
346 {
347 return (_beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL));
348 }
349
350
351 /*
352 * '_cupsThreadDetach()' - Tell the OS that the thread is running independently.
353 */
354
355 void
356 _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */
357 {
358 // TODO: Implement me
359 (void)thread;
360 }
361
362
363 /*
364 * '_cupsThreadWait()' - Wait for a thread to exit.
365 */
366
367 void * /* O - Return value */
368 _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */
369 {
370 // TODO: Implement me
371 (void)thread;
372
373 return (NULL);
374 }
375
376
377 #else /* No threading */
378 /*
379 * '_cupsCondBroadcast()' - Wake up waiting threads.
380 */
381
382 void
383 _cupsCondBroadcast(_cups_cond_t *cond) /* I - Condition */
384 {
385 // TODO: Implement me
386 }
387
388
389 /*
390 * '_cupsCondInit()' - Initialize a condition variable.
391 */
392
393 void
394 _cupsCondInit(_cups_cond_t *cond) /* I - Condition */
395 {
396 // TODO: Implement me
397 }
398
399
400 /*
401 * '_cupsCondWait()' - Wait for a condition with optional timeout.
402 */
403
404 void
405 _cupsCondWait(_cups_cond_t *cond, /* I - Condition */
406 _cups_mutex_t *mutex, /* I - Mutex */
407 double timeout) /* I - Timeout in seconds (0 or negative for none) */
408 {
409 // TODO: Implement me
410 }
411
412
413 /*
414 * '_cupsMutexInit()' - Initialize a mutex.
415 */
416
417 void
418 _cupsMutexInit(_cups_mutex_t *mutex) /* I - Mutex */
419 {
420 (void)mutex;
421 }
422
423
424 /*
425 * '_cupsMutexLock()' - Lock a mutex.
426 */
427
428 void
429 _cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */
430 {
431 (void)mutex;
432 }
433
434
435 /*
436 * '_cupsMutexUnlock()' - Unlock a mutex.
437 */
438
439 void
440 _cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
441 {
442 (void)mutex;
443 }
444
445
446 /*
447 * '_cupsRWInit()' - Initialize a reader/writer lock.
448 */
449
450 void
451 _cupsRWInit(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
452 {
453 (void)rwlock;
454 }
455
456
457 /*
458 * '_cupsRWLockRead()' - Acquire a reader/writer lock for reading.
459 */
460
461 void
462 _cupsRWLockRead(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
463 {
464 (void)rwlock;
465 }
466
467
468 /*
469 * '_cupsRWLockWrite()' - Acquire a reader/writer lock for writing.
470 */
471
472 void
473 _cupsRWLockWrite(_cups_rwlock_t *rwlock)/* I - Reader/writer lock */
474 {
475 (void)rwlock;
476 }
477
478
479 /*
480 * '_cupsRWUnlock()' - Release a reader/writer lock.
481 */
482
483 void
484 _cupsRWUnlock(_cups_rwlock_t *rwlock) /* I - Reader/writer lock */
485 {
486 (void)rwlock;
487 }
488
489
490 /*
491 * '_cupsThreadCancel()' - Cancel (kill) a thread.
492 */
493
494 void
495 _cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */
496 {
497 (void)thread;
498 }
499
500
501 /*
502 * '_cupsThreadCreate()' - Create a thread.
503 */
504
505 _cups_thread_t /* O - Thread ID */
506 _cupsThreadCreate(
507 _cups_thread_func_t func, /* I - Entry point */
508 void *arg) /* I - Entry point context */
509 {
510 fputs("DEBUG: CUPS was compiled without threading support, no thread created.\n", stderr);
511
512 (void)func;
513 (void)arg;
514
515 return (0);
516 }
517
518
519 /*
520 * '_cupsThreadDetach()' - Tell the OS that the thread is running independently.
521 */
522
523 void
524 _cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */
525 {
526 (void)thread;
527 }
528
529
530 /*
531 * '_cupsThreadWait()' - Wait for a thread to exit.
532 */
533
534 void * /* O - Return value */
535 _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */
536 {
537 (void)thread;
538
539 return (NULL);
540 }
541
542 #endif /* HAVE_PTHREAD_H */