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