VirtualBox

source: vbox/trunk/include/iprt/semaphore.h@ 25374

Last change on this file since 25374 was 25373, checked in by vboxsync, 15 years ago

IPRT,PDMCritSect: More validation changes. Validate posix and linux mutexes. Always update the thread state with critsects.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.7 KB
Line 
1/** @file
2 * IPRT - Semaphore.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 *
25 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___iprt_semaphore_h
31#define ___iprt_semaphore_h
32
33#include <iprt/cdefs.h>
34#include <iprt/types.h>
35
36
37RT_C_DECLS_BEGIN
38
39/** @defgroup grp_rt_sems RTSem - Semaphores
40 *
41 * This module implements all kinds of event and mutex semaphores; in addition
42 * to these, IPRT implements "critical sections", which are fast recursive
43 * mutexes (see @ref grp_rt_critsect ).
44 *
45 * @ingroup grp_rt
46 * @{
47 */
48
49
50/** @defgroup grp_rt_sems_event RTSemEvent - Single Release Event Semaphores
51 *
52 * Event semaphores can be used for inter-process communication when
53 * one thread wants to notify another thread that something happened.
54 * A thread can block ("wait") on an event semaphore until it is
55 * signalled by another thread; see RTSemEventCreate, RTSemEventSignal
56 * and RTSemEventWait.
57 *
58 * @{ */
59
60/**
61 * Create a event semaphore.
62 *
63 * @returns iprt status code.
64 * @param pEventSem Where to store the event semaphore handle.
65 */
66RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem);
67
68/**
69 * Destroy an event semaphore.
70 *
71 * @returns iprt status code.
72 * @param EventSem Handle of the
73 */
74RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem);
75
76/**
77 * Signal an event semaphore.
78 *
79 * The event semaphore will be signaled and automatically reset
80 * after exactly one thread have successfully returned from
81 * RTSemEventWait() after waiting/polling on that semaphore.
82 *
83 * @returns iprt status code.
84 * @param EventSem The event semaphore to signal.
85 */
86RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem);
87
88/**
89 * Wait for the event semaphore to be signaled, resume on interruption.
90 *
91 * This function will resume if the wait is interrupted by an async
92 * system event (like a unix signal) or similar.
93 *
94 * @returns iprt status code.
95 * Will not return VERR_INTERRUPTED.
96 * @param EventSem The event semaphore to wait on.
97 * @param cMillies Number of milliseconds to wait.
98 */
99RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies);
100
101/**
102 * Wait for the event semaphore to be signaled, return on interruption.
103 *
104 * This function will not resume the wait if interrupted.
105 *
106 * @returns iprt status code.
107 * @param EventSem The event semaphore to wait on.
108 * @param cMillies Number of milliseconds to wait.
109 */
110RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies);
111
112/** @} */
113
114
115/** @defgroup grp_rt_sems_event_multi RTSemEventMulti - Multiple Release Event Semaphores
116 * @{ */
117
118/**
119 * Create a event multi semaphore.
120 *
121 * @returns iprt status code.
122 * @param pEventMultiSem Where to store the event multi semaphore handle.
123 */
124RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem);
125
126/**
127 * Destroy an event multi semaphore.
128 *
129 * @returns iprt status code.
130 * @param EventMultiSem The event multi sempahore to destroy.
131 */
132RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem);
133
134/**
135 * Signal an event multi semaphore.
136 *
137 * @returns iprt status code.
138 * @param EventMultiSem The event multi semaphore to signal.
139 */
140RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem);
141
142/**
143 * Resets an event multi semaphore to non-signaled state.
144 *
145 * @returns iprt status code.
146 * @param EventMultiSem The event multi semaphore to reset.
147 */
148RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem);
149
150/**
151 * Wait for the event multi semaphore to be signaled, resume on interruption.
152 *
153 * This function will resume if the wait is interrupted by an async
154 * system event (like a unix signal) or similar.
155 *
156 * @returns iprt status code.
157 * Will not return VERR_INTERRUPTED.
158 * @param EventMultiSem The event multi semaphore to wait on.
159 * @param cMillies Number of milliseconds to wait.
160 */
161RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies);
162
163
164/**
165 * Wait for the event multi semaphore to be signaled, return on interruption.
166 *
167 * This function will not resume the wait if interrupted.
168 *
169 * @returns iprt status code.
170 * @param EventMultiSem The event multi semaphore to wait on.
171 * @param cMillies Number of milliseconds to wait.
172 */
173RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies);
174
175/** @} */
176
177
178/** @defgroup grp_rt_sems_mutex RTMutex - Mutex semaphores.
179 *
180 * Mutex semaphores protect a section of code or data to which access
181 * must be exclusive. Only one thread can hold access to a critical
182 * section at one time. See RTSemMutexCreate, RTSemMutexRequest and
183 * RTSemMutexRelease.
184 *
185 * @remarks These are less efficient than "fast mutexes" and "critical sections",
186 * which IPRT implements as well; see @ref grp_rt_sems_fast_mutex and
187 * @ref grp_rt_critsect .
188 *
189 * @{ */
190
191/**
192 * Create a mutex semaphore.
193 *
194 * @returns iprt status code.
195 * @param pMutexSem Where to store the mutex semaphore handle.
196 */
197RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem);
198
199/**
200 * Destroy a mutex semaphore.
201 *
202 * @returns iprt status code.
203 * @param MutexSem The mutex semaphore to destroy.
204 */
205RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem);
206
207/**
208 * Request ownership of a mutex semaphore, resume on interruption.
209 *
210 * This function will resume if the wait is interrupted by an async
211 * system event (like a unix signal) or similar.
212 *
213 * The same thread may request a mutex semaphore multiple times,
214 * a nested counter is kept to make sure it's released on the right
215 * RTSemMutexRelease() call.
216 *
217 * @returns iprt status code.
218 * Will not return VERR_INTERRUPTED.
219 * @param MutexSem The mutex semaphore to request ownership over.
220 * @param cMillies The number of milliseconds to wait.
221 */
222RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies);
223
224/**
225 * Request ownership of a mutex semaphore, return on interruption.
226 *
227 * This function will not resume the wait if interrupted.
228 *
229 * The same thread may request a mutex semaphore multiple times,
230 * a nested counter is kept to make sure it's released on the right
231 * RTSemMutexRelease() call.
232 *
233 * @returns iprt status code.
234 * @param MutexSem The mutex semaphore to request ownership over.
235 * @param cMillies The number of milliseconds to wait.
236 */
237RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies);
238
239/**
240 * Debug version of RTSemMutexRequest that tracks the location.
241 *
242 * @returns iprt status code.
243 * Will not return VERR_INTERRUPTED.
244 * @param MutexSem The mutex semaphore to request ownership over.
245 * @param cMillies The number of milliseconds to wait.
246 * @param uId
247 * @param uId Some kind of locking location ID. Typically a
248 * return address up the stack. Optional (0).
249 * @param pszFile The file where the lock is being acquired from.
250 * Optional.
251 * @param iLine The line number in that file. Optional (0).
252 * @param pszFunction The functionn where the lock is being acquired
253 * from. Optional.
254 */
255RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
256
257/**
258 * Debug version of RTSemMutexRequestNoResume that tracks the location.
259 *
260 * @returns iprt status code.
261 * Will not return VERR_INTERRUPTED.
262 * @param MutexSem The mutex semaphore to request ownership over.
263 * @param cMillies The number of milliseconds to wait.
264 * @param uId
265 * @param uId Some kind of locking location ID. Typically a
266 * return address up the stack. Optional (0).
267 * @param pszFile The file where the lock is being acquired from.
268 * Optional.
269 * @param iLine The line number in that file. Optional (0).
270 * @param pszFunction The functionn where the lock is being acquired
271 * from. Optional.
272 */
273RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
274
275/**
276 * Release the ownership of a mutex semaphore.
277 *
278 * @returns iprt status code.
279 * @param MutexSem The mutex to release the ownership of.
280 * It goes without saying the the calling thread must own it.
281 */
282RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem);
283
284/** @} */
285
286
287/** @defgroup grp_rt_sems_fast_mutex RTSemFastMutex - Fast Mutex Semaphores
288 *
289 * Fast mutexes work like regular mutexes in that they allow only
290 * a single thread access to a critical piece of code or data.
291 * As opposed to mutexes, they require no syscall if the fast mutex
292 * is not held (like critical sections). Unlike critical sections however,
293 * they are *not* recursive.
294 *
295 * @{ */
296
297/**
298 * Create a fast mutex semaphore.
299 *
300 * @returns iprt status code.
301 * @param pMutexSem Where to store the mutex semaphore handle.
302 *
303 * @remarks Fast mutex semaphores are not recursive.
304 */
305RTDECL(int) RTSemFastMutexCreate(PRTSEMFASTMUTEX pMutexSem);
306
307/**
308 * Destroy a fast mutex semaphore.
309 *
310 * @returns iprt status code.
311 * @param MutexSem The mutex semaphore to destroy.
312 */
313RTDECL(int) RTSemFastMutexDestroy(RTSEMFASTMUTEX MutexSem);
314
315/**
316 * Request ownership of a fast mutex semaphore.
317 *
318 * The same thread may request a mutex semaphore multiple times,
319 * a nested counter is kept to make sure it's released on the right
320 * RTSemMutexRelease() call.
321 *
322 * @returns iprt status code.
323 * @param MutexSem The mutex semaphore to request ownership over.
324 */
325RTDECL(int) RTSemFastMutexRequest(RTSEMFASTMUTEX MutexSem);
326
327/**
328 * Release the ownership of a fast mutex semaphore.
329 *
330 * @returns iprt status code.
331 * @param MutexSem The mutex to release the ownership of.
332 * It goes without saying the the calling thread must own it.
333 */
334RTDECL(int) RTSemFastMutexRelease(RTSEMFASTMUTEX MutexSem);
335
336/** @} */
337
338
339/** @defgroup grp_rt_sems_spin_mutex RTSemSpinMutex - Spinning Mutex Semaphores
340 *
341 * Very adaptive kind of mutex semaphore tailored for the ring-0 logger.
342 *
343 * @{ */
344
345/**
346 * Creates a spinning mutex semaphore.
347 *
348 * @returns iprt status code.
349 * @retval VERR_INVALID_PARAMETER on invalid flags.
350 * @retval VERR_NO_MEMORY if out of memory for the semaphore structure and
351 * handle.
352 *
353 * @param phSpinMtx Where to return the handle to the create semaphore.
354 * @param fFlags Flags, see RTSEMSPINMUTEX_FLAGS_XXX.
355 */
356RTDECL(int) RTSemSpinMutexCreate(PRTSEMSPINMUTEX phSpinMtx, uint32_t fFlags);
357
358/** @name RTSemSpinMutexCreate flags.
359 * @{ */
360/** Always take the semaphore in a IRQ safe way.
361 * (In plain words: always disable interrupts.) */
362#define RTSEMSPINMUTEX_FLAGS_IRQ_SAFE RT_BIT_32(0)
363/** Mask of valid flags. */
364#define RTSEMSPINMUTEX_FLAGS_VALID_MASK UINT32_C(0x00000001)
365/** @} */
366
367/**
368 * Destroys a spinning mutex semaphore.
369 *
370 * @returns iprt status code.
371 * @retval VERR_INVALID_HANDLE (or crash) if the handle is invalid. (NIL will
372 * not cause this status.)
373 *
374 * @param hSpinMtx The semaphore handle. NIL_RTSEMSPINMUTEX is ignored
375 * quietly (VINF_SUCCESS).
376 */
377RTDECL(int) RTSemSpinMutexDestroy(RTSEMSPINMUTEX hSpinMtx);
378
379/**
380 * Request the spinning mutex semaphore.
381 *
382 * This may block if the context we're called in allows this. If not it will
383 * spin. If called in an interrupt context, we will only spin if the current
384 * owner isn't interrupted. Also, on some systems it is not always possible to
385 * wake up blocking threads in all contexts, so, which will either be indicated
386 * by returning VERR_SEM_BAD_CONTEXT or by temporarily switching the semaphore
387 * into pure spinlock state.
388 *
389 * Preemption will be disabled upon return. IRQs may also be disabled.
390 *
391 * @returns iprt status code.
392 * @retval VERR_SEM_BAD_CONTEXT if the context it's called in isn't suitable
393 * for releasing it if someone is sleeping on it.
394 * @retval VERR_SEM_DESTROYED if destroyed.
395 * @retval VERR_SEM_NESTED if held by the caller. Asserted.
396 * @retval VERR_INVALID_HANDLE if the handle is invalid. Asserted
397 *
398 * @param hSpinMtx The semaphore handle.
399 */
400RTDECL(int) RTSemSpinMutexRequest(RTSEMSPINMUTEX hSpinMtx);
401
402/**
403 * Like RTSemSpinMutexRequest but it won't block or spin if the semaphore is
404 * held by someone else.
405 *
406 * @returns iprt status code.
407 * @retval VERR_SEM_BUSY if held by someone else.
408 * @retval VERR_SEM_DESTROYED if destroyed.
409 * @retval VERR_SEM_NESTED if held by the caller. Asserted.
410 * @retval VERR_INVALID_HANDLE if the handle is invalid. Asserted
411 *
412 * @param hSpinMtx The semaphore handle.
413 */
414RTDECL(int) RTSemSpinMutexTryRequest(RTSEMSPINMUTEX hSpinMtx);
415
416/**
417 * Releases the semaphore previously acquired by RTSemSpinMutexRequest or
418 * RTSemSpinMutexTryRequest.
419 *
420 * @returns iprt status code.
421 * @retval VERR_SEM_DESTROYED if destroyed.
422 * @retval VERR_NOT_OWNER if not owner. Asserted.
423 * @retval VERR_INVALID_HANDLE if the handle is invalid. Asserted.
424 *
425 * @param hSpinMtx The semaphore handle.
426 */
427RTDECL(int) RTSemSpinMutexRelease(RTSEMSPINMUTEX hSpinMtx);
428
429/** @} */
430
431
432/** @defgroup grp_rt_sem_rw RTSemRW - Read / Write Semaphores
433 *
434 * Read/write semaphores are a fancier version of mutexes in that they
435 * grant read access to the protected data to several threads
436 * at the same time but allow only one writer at a time. This can make
437 * code scale better at the expense of slightly more overhead in
438 * mutex management.
439 *
440 * @{ */
441
442/**
443 * Creates a read/write semaphore.
444 *
445 * @returns iprt status code.
446 * @param pRWSem Where to store the handle to the created RW semaphore.
447 */
448RTDECL(int) RTSemRWCreate(PRTSEMRW pRWSem);
449
450/**
451 * Destroys a read/write semaphore.
452 *
453 * @returns iprt status code.
454 * @param RWSem The Read/Write semaphore to destroy.
455 */
456RTDECL(int) RTSemRWDestroy(RTSEMRW RWSem);
457
458/**
459 * Request read access to a read/write semaphore, resume on interruption
460 *
461 * @returns iprt status code.
462 * @retval VINF_SUCCESS on success.
463 * @retval VERR_INTERRUPT if the wait was interrupted.
464 * @retval VERR_INVALID_HANDLE if RWSem is invalid.
465 *
466 * @param RWSem The Read/Write semaphore to request read access to.
467 * @param cMillies The number of milliseconds to wait.
468 */
469RTDECL(int) RTSemRWRequestRead(RTSEMRW RWSem, unsigned cMillies);
470
471/**
472 * Request read access to a read/write semaphore, return on interruption
473 *
474 * @returns iprt status code.
475 * @retval VINF_SUCCESS on success.
476 * @retval VERR_INTERRUPT if the wait was interrupted.
477 * @retval VERR_INVALID_HANDLE if RWSem is invalid.
478 *
479 * @param RWSem The Read/Write semaphore to request read access to.
480 * @param cMillies The number of milliseconds to wait.
481 */
482RTDECL(int) RTSemRWRequestReadNoResume(RTSEMRW RWSem, unsigned cMillies);
483
484/**
485 * Release read access to a read/write semaphore.
486 *
487 * @returns iprt status code.
488 * @param RWSem The Read/Write sempahore to release read access to.
489 * Goes without saying that caller must have read access to the sem.
490 */
491RTDECL(int) RTSemRWReleaseRead(RTSEMRW RWSem);
492
493/**
494 * Request write access to a read/write semaphore, resume on interruption.
495 *
496 * @returns iprt status code.
497 * @retval VINF_SUCCESS on success.
498 * @retval VERR_DEADLOCK if the caller owned the read lock.
499 * @retval VERR_INVALID_HANDLE if RWSem is invalid.
500 *
501 * @param RWSem The Read/Write semaphore to request write access to.
502 * @param cMillies The number of milliseconds to wait.
503 */
504RTDECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies);
505
506/**
507 * Request write access to a read/write semaphore, return on interruption.
508 *
509 * @returns iprt status code.
510 * @retval VINF_SUCCESS on success.
511 * @retval VERR_INTERRUPT if the wait was interrupted.
512 * @retval VERR_DEADLOCK if the caller owned the read lock.
513 * @retval VERR_INVALID_HANDLE if RWSem is invalid.
514 *
515 * @param RWSem The Read/Write semaphore to request write access to.
516 * @param cMillies The number of milliseconds to wait.
517 */
518RTDECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies);
519
520/**
521 * Release write access to a read/write semaphore.
522 *
523 * @returns iprt status code.
524 * @param RWSem The Read/Write sempahore to release read access to.
525 * Goes without saying that caller must have write access to the sem.
526 */
527RTDECL(int) RTSemRWReleaseWrite(RTSEMRW RWSem);
528
529/**
530 * Checks if the caller is the exclusive semaphore owner.
531 *
532 * @returns true / false accoringly.
533 * @param RWSem The Read/Write semaphore in question.
534 */
535RTDECL(bool) RTSemRWIsWriteOwner(RTSEMRW RWSem);
536
537/**
538 * Gets the write recursion count.
539 *
540 * @returns The write recursion count (0 if bad semaphore handle).
541 * @param RWSem The Read/Write semaphore in question.
542 */
543RTDECL(uint32_t) RTSemRWGetWriteRecursion(RTSEMRW RWSem);
544
545/**
546 * Gets the read recursion count of the current writer.
547 *
548 * @returns The read recursion count (0 if bad semaphore handle).
549 * @param RWSem The Read/Write semaphore in question.
550 */
551RTDECL(uint32_t) RTSemRWGetWriterReadRecursion(RTSEMRW RWSem);
552
553/** @} */
554
555
556/** @defgroup grp_rt_sems_pingpong RTSemPingPong - Ping-Pong Construct
557 * @{ */
558
559/**
560 * Ping-pong speaker
561 */
562typedef enum RTPINGPONGSPEAKER
563{
564 /** Not initialized. */
565 RTPINGPONGSPEAKER_UNINITIALIZE = 0,
566 /** Ping is speaking, Pong is waiting. */
567 RTPINGPONGSPEAKER_PING,
568 /** Pong is signaled, Ping is waiting. */
569 RTPINGPONGSPEAKER_PONG_SIGNALED,
570 /** Pong is speaking, Ping is waiting. */
571 RTPINGPONGSPEAKER_PONG,
572 /** Ping is signaled, Pong is waiting. */
573 RTPINGPONGSPEAKER_PING_SIGNALED,
574 /** Hack to ensure that it's at least 32-bits wide. */
575 RTPINGPONGSPEAKER_HACK = 0x7fffffff
576} RTPINGPONGSPEAKER;
577
578/**
579 * Ping-Pong construct.
580 *
581 * Two threads, one saying Ping and the other saying Pong. The construct
582 * makes sure they don't speak out of turn and that they can wait and poll
583 * on the conversation.
584 */
585typedef struct RTPINGPONG
586{
587 /** The semaphore the Ping thread waits on. */
588 RTSEMEVENT Ping;
589 /** The semaphore the Pong thread waits on. */
590 RTSEMEVENT Pong;
591 /** The current speaker. */
592 volatile RTPINGPONGSPEAKER enmSpeaker;
593#if HC_ARCH_BITS == 64
594 /** Padding the structure to become a multiple of sizeof(RTHCPTR). */
595 uint32_t u32Padding;
596#endif
597} RTPINGPONG;
598/** Pointer to Ping-Pong construct. */
599typedef RTPINGPONG *PRTPINGPONG;
600
601/**
602 * Init a Ping-Pong construct.
603 *
604 * @returns iprt status code.
605 * @param pPP Pointer to the ping-pong structure which needs initialization.
606 */
607RTDECL(int) RTSemPingPongInit(PRTPINGPONG pPP);
608
609/**
610 * Deletes a Ping-Pong construct.
611 *
612 * @returns iprt status code.
613 * @param pPP Pointer to the ping-pong structure which is to be destroyed.
614 * (I.e. put into uninitialized state.)
615 */
616RTDECL(int) RTSemPingPongDelete(PRTPINGPONG pPP);
617
618/**
619 * Signals the pong thread in a ping-pong construct. (I.e. sends ping.)
620 * This is called by the ping thread.
621 *
622 * @returns iprt status code.
623 * @param pPP Pointer to the ping-pong structure to ping.
624 */
625RTDECL(int) RTSemPing(PRTPINGPONG pPP);
626
627/**
628 * Signals the ping thread in a ping-pong construct. (I.e. sends pong.)
629 * This is called by the pong thread.
630 *
631 * @returns iprt status code.
632 * @param pPP Pointer to the ping-pong structure to pong.
633 */
634RTDECL(int) RTSemPong(PRTPINGPONG pPP);
635
636/**
637 * Wait function for the ping thread.
638 *
639 * @returns iprt status code.
640 * Will not return VERR_INTERRUPTED.
641 * @param pPP Pointer to the ping-pong structure to wait on.
642 * @param cMillies Number of milliseconds to wait.
643 */
644RTDECL(int) RTSemPingWait(PRTPINGPONG pPP, unsigned cMillies);
645
646/**
647 * Wait function for the pong thread.
648 *
649 * @returns iprt status code.
650 * Will not return VERR_INTERRUPTED.
651 * @param pPP Pointer to the ping-pong structure to wait on.
652 * @param cMillies Number of milliseconds to wait.
653 */
654RTDECL(int) RTSemPongWait(PRTPINGPONG pPP, unsigned cMillies);
655
656
657/**
658 * Checks if the pong thread is speaking.
659 *
660 * @returns true / false.
661 * @param pPP Pointer to the ping-pong structure.
662 * @remark This is NOT the same as !RTSemPongIsSpeaker().
663 */
664DECLINLINE(bool) RTSemPingIsSpeaker(PRTPINGPONG pPP)
665{
666 RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
667 return enmSpeaker == RTPINGPONGSPEAKER_PING;
668}
669
670
671/**
672 * Checks if the pong thread is speaking.
673 *
674 * @returns true / false.
675 * @param pPP Pointer to the ping-pong structure.
676 * @remark This is NOT the same as !RTSemPingIsSpeaker().
677 */
678DECLINLINE(bool) RTSemPongIsSpeaker(PRTPINGPONG pPP)
679{
680 RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
681 return enmSpeaker == RTPINGPONGSPEAKER_PONG;
682}
683
684
685/**
686 * Checks whether the ping thread should wait.
687 *
688 * @returns true / false.
689 * @param pPP Pointer to the ping-pong structure.
690 * @remark This is NOT the same as !RTSemPongShouldWait().
691 */
692DECLINLINE(bool) RTSemPingShouldWait(PRTPINGPONG pPP)
693{
694 RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
695 return enmSpeaker == RTPINGPONGSPEAKER_PONG
696 || enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED
697 || enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED;
698}
699
700
701/**
702 * Checks whether the pong thread should wait.
703 *
704 * @returns true / false.
705 * @param pPP Pointer to the ping-pong structure.
706 * @remark This is NOT the same as !RTSemPingShouldWait().
707 */
708DECLINLINE(bool) RTSemPongShouldWait(PRTPINGPONG pPP)
709{
710 RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
711 return enmSpeaker == RTPINGPONGSPEAKER_PING
712 || enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED
713 || enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED;
714}
715
716/** @} */
717
718/** @} */
719
720RT_C_DECLS_END
721
722#endif
723
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette