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