semevent-r0drv-solaris.c revision b34f0f200ed0778053a2a1d93381c2c6b60cb2d5
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/* $Id$ */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/** @file
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * innotek Portable Runtime - Semaphores, Ring-0 Driver, Solaris.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/*
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * Copyright (C) 2006-2007 innotek GmbH
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync *
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * available from http://www.virtualbox.org. This file is free software;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * General Public License as published by the Free Software Foundation,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/*******************************************************************************
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync* Header Files *
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync*******************************************************************************/
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include "the-solaris-kernel.h"
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include <time.h>
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include <iprt/semaphore.h>
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include <iprt/alloc.h>
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include <iprt/assert.h>
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include <iprt/asm.h>
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include <iprt/err.h>
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync#include "internal/magics.h"
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/*******************************************************************************
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync* Structures and Typedefs *
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync*******************************************************************************/
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/**
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * Solaris event semaphore.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsynctypedef struct RTSEMEVENTINTERNAL
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync{
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** Magic value (RTSEMEVENT_MAGIC). */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync uint32_t volatile u32Magic;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The number of waiting threads. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync uint32_t volatile cWaiters;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** Set if the event object is signaled. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync uint8_t volatile fSignaled;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The number of threads in the process of waking up. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync uint32_t volatile cWaking;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The Solaris mutex protecting this structure and pairing up the with the cv. */
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync kmutex_t Mtx;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The Solaris condition variable. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync kcondvar_t Cnd;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync} RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsyncRTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync{
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertPtrReturn(pEventSem, VERR_INVALID_POINTER);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync pEventInt->u32Magic = RTSEMEVENT_MAGIC;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync pEventInt->cWaiters = 0;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync pEventInt->cWaking = 0;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync pEventInt->fSignaled = 0;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_init(&pEventInt->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, NULL);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cv_init(&pEventInt->Cnd, "IPRT CV", CV_DRIVER, NULL);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync *pEventSem = pEventInt;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync return VINF_SUCCESS;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync return VERR_NO_MEMORY;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync}
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsyncRTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync{
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (EventSem == NIL_RTSEMEVENT)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync return VERR_INVALID_HANDLE;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync VERR_INVALID_HANDLE);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_enter(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt->cWaiters > 0)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* abort waiting thread, last man cleans up. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicXchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cv_signal(&pEventInt->Cnd);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_exit(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else if (pEventInt->cWaking)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* the last waking thread is gonna do the cleanup */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_exit(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_exit(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cv_destroy(&pEventInt->Cnd);
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync mutex_destroy(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync RTMemFree(pEventInt);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync return VINF_SUCCESS;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync}
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsyncRTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync{
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync VERR_INVALID_HANDLE);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_enter(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt->cWaiters > 0)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicDecU32(&pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicIncU32(&pEventInt->cWaking);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cv_signal(&pEventInt->Cnd);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicXchgU8(&pEventInt->fSignaled, true);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_exit(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync return VINF_SUCCESS;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync}
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsyncRTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync{
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync int rc;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync VERR_INVALID_HANDLE);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_enter(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt->fSignaled)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync Assert(!pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicXchgU8(&pEventInt->fSignaled, false);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = VINF_SUCCESS;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync unsigned long timeout;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync drv_getparm(LBOLT, &timeout);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /*
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * Translate milliseconds into ticks and go to sleep.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync int cTicks;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (cMillies != RT_INDEFINITE_WAIT)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cTicks = drv_usectohz((clock_t)(cMillies * 1000L));
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cTicks = 0;
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync timeout += cTicks;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicIncU32(&pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** @todo r=bird: Is this interruptible or non-interruptible? */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = cv_timedwait_sig(&pEventInt->Cnd, &pEventInt->Mtx, timeout);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (rc > 0)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* Retured due to call to cv_signal() or cv_broadcast() */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = VERR_SEM_DESTROYED;
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync if (!ASMAtomicDecU32(&pEventInt->cWaking))
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync {
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync mutex_exit(&pEventInt->Mtx);
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync cv_destroy(&pEventInt->Cnd);
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync mutex_destroy(&pEventInt->Mtx);
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync RTMemFree(pEventInt);
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync return rc;
b34f0f200ed0778053a2a1d93381c2c6b60cb2d5vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicDecU32(&pEventInt->cWaking);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = VINF_SUCCESS;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else if (rc == -1)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* Returned due to timeout being reached */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt->cWaiters > 0)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicDecU32(&pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = VERR_TIMEOUT;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync else
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync {
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* Returned due to pending signal */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync if (pEventInt->cWaiters > 0)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicDecU32(&pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = VERR_INTERRUPTED;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync }
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_exit(&pEventInt->Mtx);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync return rc;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync}
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/** @todo Implement RTSemEventWaitNoResume (interruptible variant of the uninterruptible RTSemEventWait()). */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync