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