Coverage Report

Created: 2025-08-28 07:06

/src/cups/cups/thread.c
Line
Count
Source (jump to first uncovered line)
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
0
{
31
0
  pthread_cond_broadcast(cond);
32
0
}
33
34
35
/*
36
 * '_cupsCondInit()' - Initialize a condition variable.
37
 */
38
39
void
40
_cupsCondInit(_cups_cond_t *cond) /* I - Condition */
41
0
{
42
0
  pthread_cond_init(cond, NULL);
43
0
}
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
0
{
55
0
  if (timeout > 0.0)
56
0
  {
57
0
    struct timespec abstime;    /* Timeout */
58
59
0
    clock_gettime(CLOCK_REALTIME, &abstime);
60
61
0
    abstime.tv_sec  += (long)timeout;
62
0
    abstime.tv_nsec += (long)(1000000000 * (timeout - (long)timeout));
63
64
0
    while (abstime.tv_nsec >= 1000000000)
65
0
    {
66
0
      abstime.tv_nsec -= 1000000000;
67
0
      abstime.tv_sec ++;
68
0
    };
69
70
0
    pthread_cond_timedwait(cond, mutex, &abstime);
71
0
  }
72
0
  else
73
0
    pthread_cond_wait(cond, mutex);
74
0
}
75
76
77
/*
78
 * '_cupsMutexInit()' - Initialize a mutex.
79
 */
80
81
void
82
_cupsMutexInit(_cups_mutex_t *mutex)  /* I - Mutex */
83
0
{
84
0
  pthread_mutex_init(mutex, NULL);
85
0
}
86
87
88
/*
89
 * '_cupsMutexLock()' - Lock a mutex.
90
 */
91
92
void
93
_cupsMutexLock(_cups_mutex_t *mutex)  /* I - Mutex */
94
0
{
95
0
  pthread_mutex_lock(mutex);
96
0
}
97
98
99
/*
100
 * '_cupsMutexUnlock()' - Unlock a mutex.
101
 */
102
103
void
104
_cupsMutexUnlock(_cups_mutex_t *mutex)  /* I - Mutex */
105
0
{
106
0
  pthread_mutex_unlock(mutex);
107
0
}
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
0
{
117
0
  pthread_rwlock_init(rwlock, NULL);
118
0
}
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
0
{
128
0
  pthread_rwlock_rdlock(rwlock);
129
0
}
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
0
{
139
0
  pthread_rwlock_wrlock(rwlock);
140
0
}
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
0
{
150
0
  pthread_rwlock_unlock(rwlock);
151
0
}
152
153
154
/*
155
 * '_cupsThreadCancel()' - Cancel (kill) a thread.
156
 */
157
158
void
159
_cupsThreadCancel(_cups_thread_t thread)/* I - Thread ID */
160
0
{
161
0
  pthread_cancel(thread);
162
0
}
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
0
{
174
0
  pthread_t thread;
175
176
0
  if (pthread_create(&thread, NULL, (void *(*)(void *))func, arg))
177
0
    return (0);
178
0
  else
179
0
    return (thread);
180
0
}
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
0
{
190
0
  pthread_detach(thread);
191
0
}
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
0
{
201
0
  void  *ret;       /* Return value */
202
203
204
0
  if (pthread_join(thread, &ret))
205
0
    return (NULL);
206
0
  else
207
0
    return (ret);
208
0
}
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 */