VirtualBox

Changeset 32966 in vbox for trunk/src


Ignore:
Timestamp:
Oct 7, 2010 8:32:37 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66471
Message:

semeventmulti-posix.cpp: Implemented RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.

Location:
trunk/src/VBox/Runtime
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r32946 r32966  
    503503        generic/RTLogWriteDebugger-generic.cpp \
    504504        generic/RTProcDaemonize-generic.cpp \
     505        generic/RTSemEventMultiWait-2-ex-generic.cpp \
     506        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
    505507        generic/RTTimeLocalNow-generic.cpp \
    506508        generic/RTTimerCreate-generic.cpp \
     
    545547        r3/linux/semeventmulti-linux.cpp \
    546548        r3/linux/semmutex-linux.cpp
    547 #       generic/RTSemEventMultiWait-2-ex-generic.cpp \
    548 #       generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
    549549else
    550550 RuntimeR3_SOURCES.linux.x86 += \
     
    555555        r3/linux/semevent-linux.cpp \
    556556        r3/linux/semeventmulti-linux.cpp
    557 #       generic/RTSemEventMultiWait-2-ex-generic.cpp \
    558 #       generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
    559557 ifdef RT_NEW_LINUX_MUTEX_CODE
    560558  RuntimeR3_SOURCES.linux.amd64 += \
     
    631629        generic/RTUuidCreate-generic.cpp \
    632630        generic/mppresent-generic.cpp \
     631        generic/RTSemEventMultiWait-2-ex-generic.cpp \
     632        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
    633633        generic/semrw-$(if-expr defined(VBOX_WITH_LOCKLESS_SEMRW),lockless-,)generic.cpp \
    634634        generic/timer-generic.cpp \
     
    672672        generic/RTFileMove-generic.cpp \
    673673        generic/RTLogWriteDebugger-generic.cpp \
     674        generic/RTSemEventMultiWait-2-ex-generic.cpp \
     675        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
    674676        generic/RTSystemQueryDmiString-generic.cpp \
    675677        generic/RTTimeLocalNow-generic.cpp \
     
    729731        generic/RTProcDaemonize-generic.cpp \
    730732        generic/RTProcIsRunningByName-generic.cpp \
     733        generic/RTSemEventMultiWait-2-ex-generic.cpp \
     734        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
    731735        generic/RTTimeLocalNow-generic.cpp \
    732736        generic/RTTimerCreate-generic.cpp \
  • trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp

    r28800 r32966  
    3636#include <iprt/lockvalidator.h>
    3737#include <iprt/mem.h>
     38#include <iprt/time.h>
    3839
    3940#include "internal/strict.h"
     
    6869    bool volatile       fEverHadSignallers;
    6970#endif
     71    /** Set if we're using the monotonic clock. */
     72    bool                fMonotonicClock;
    7073};
    7174
     
    107110        if (!rc)
    108111        {
     112#if defined(CLOCK_MONOTONIC) \
     113 && (   (defined(RT_OS_LINUX) && defined(__USE_XOPEN2K) /** @todo check ancient glibc versions */) \
     114     || /** @todo check other platforms */ 0)
     115            /* ASSUMES RTTimeSystemNanoTS() == RTTimeNanoTS() == clock_gettime(CLOCK_MONOTONIC). */
     116            rc = pthread_condattr_setclock(&CondAttr, CLOCK_MONOTONIC);
     117            pThis->fMonotonicClock = rc == 0;
     118#else
     119            pThis->fMonotonicClock = false;
     120#endif
    109121            rc = pthread_cond_init(&pThis->Cond, &CondAttr);
    110122            if (!rc)
     
    329341
    330342
    331 static int rtSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies, bool fAutoResume)
    332 {
    333     PCRTLOCKVALSRCPOS pSrcPos = NULL;
    334 
    335     /*
    336      * Validate input.
    337      */
    338     struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
    339     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    340     uint32_t u32 = pThis->u32State;
    341     AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
    342 
    343     /*
    344      * Timed or indefinite wait?
    345      */
    346     if (cMillies == RT_INDEFINITE_WAIT)
    347     {
    348         /* take mutex */
    349         int rc = pthread_mutex_lock(&pThis->Mutex);
    350         if (rc)
    351         {
    352             AssertMsgFailed(("Failed to lock event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
    353             return RTErrConvertFromErrno(rc);
    354         }
    355         ASMAtomicIncU32(&pThis->cWaiters);
    356 
    357         for (;;)
    358         {
    359             /* check state. */
    360             if (pThis->u32State == EVENTMULTI_STATE_SIGNALED)
     343/**
     344 * Handle polling (timeout already expired at the time of the call).
     345 *
     346 * @returns VINF_SUCCESs, VERR_TIMEOUT, VERR_SEM_DESTROYED.
     347 * @param   pThis               The semaphore.
     348 */
     349DECLINLINE(int) rtSemEventMultiPosixWaitPoll(struct RTSEMEVENTMULTIINTERNAL *pThis)
     350{
     351    int rc = pthread_mutex_lock(&pThis->Mutex);
     352    AssertMsgReturn(!rc, ("Failed to lock event multi sem %p, rc=%d.\n", pThis, rc), RTErrConvertFromErrno(rc));
     353
     354    uint32_t const u32State = pThis->u32State;
     355
     356    rc = pthread_mutex_unlock(&pThis->Mutex);
     357    AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc)); NOREF(rc);
     358
     359    return u32State == EVENTMULTI_STATE_SIGNALED
     360         ? VINF_SUCCESS
     361         : u32State != EVENTMULTI_STATE_UNINITIALIZED
     362         ? VERR_TIMEOUT
     363         : VERR_SEM_DESTROYED;
     364}
     365
     366
     367
     368/**
     369 * Implemens the indefinite wait.
     370 *
     371 * @returns See RTSemEventMultiWaitEx.
     372 * @param   pThis               The semaphore.
     373 * @param   fFlags              See RTSemEventMultiWaitEx.
     374 * @param   pSrcPos             The source position, can be NULL.
     375 */
     376static int rtSemEventMultiPosixWaitIndefinite(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, PCRTLOCKVALSRCPOS pSrcPos)
     377{
     378    /* take mutex */
     379    int rc = pthread_mutex_lock(&pThis->Mutex);
     380    AssertMsgReturn(!rc, ("Failed to lock event multi sem %p, rc=%d.\n", pThis, rc), RTErrConvertFromErrno(rc));
     381    ASMAtomicIncU32(&pThis->cWaiters);
     382
     383    for (;;)
     384    {
     385        /* check state. */
     386        uint32_t const u32State = pThis->u32State;
     387        if (u32State != EVENTMULTI_STATE_NOT_SIGNALED)
     388        {
     389            ASMAtomicDecU32(&pThis->cWaiters);
     390            rc = pthread_mutex_unlock(&pThis->Mutex);
     391            AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc));
     392            return u32State == EVENTMULTI_STATE_SIGNALED
     393                 ? VINF_SUCCESS
     394                 : VERR_SEM_DESTROYED;
     395        }
     396
     397        /* wait */
     398#ifdef RTSEMEVENTMULTI_STRICT
     399        RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     400        if (pThis->fEverHadSignallers)
     401        {
     402            rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     403                                                       RT_INDEFINITE_WAIT, RTTHREADSTATE_EVENT_MULTI, true);
     404            if (RT_FAILURE(rc))
    361405            {
    362406                ASMAtomicDecU32(&pThis->cWaiters);
    363                 rc = pthread_mutex_unlock(&pThis->Mutex);
    364                 AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
    365                 return VINF_SUCCESS;
     407                pthread_mutex_unlock(&pThis->Mutex);
     408                return rc;
    366409            }
    367             if (pThis->u32State == EVENTMULTI_STATE_UNINITIALIZED)
    368             {
    369                 rc = pthread_mutex_unlock(&pThis->Mutex);
    370                 AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
    371                 return VERR_SEM_DESTROYED;
    372             }
    373 
    374             /* wait */
    375 #ifdef RTSEMEVENTMULTI_STRICT
    376             RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
    377             if (pThis->fEverHadSignallers)
    378             {
    379                 rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
    380                                                            cMillies, RTTHREADSTATE_EVENT_MULTI, true);
    381                 if (RT_FAILURE(rc))
    382                 {
    383                     ASMAtomicDecU32(&pThis->cWaiters);
    384                     pthread_mutex_unlock(&pThis->Mutex);
    385                     return rc;
    386                 }
    387             }
     410        }
    388411#else
    389             RTTHREAD hThreadSelf = RTThreadSelf();
    390 #endif
    391             RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
    392             rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex);
    393             RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
    394             if (rc)
    395             {
    396                 AssertMsgFailed(("Failed to wait on event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
    397                 ASMAtomicDecU32(&pThis->cWaiters);
    398                 int rc2 = pthread_mutex_unlock(&pThis->Mutex);
    399                 AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc2)); NOREF(rc2);
    400                 return RTErrConvertFromErrno(rc);
    401             }
    402         }
    403     }
    404     else
    405     {
    406         /*
    407          * Get current time and calc end of wait time.
    408          */
    409         /** @todo Something is braindead here. we're getting occational timeouts after no time has
    410          * elapsed on linux 2.6.23. (ata code typically)
    411          *
    412          * The general problem here is that we're using the realtime clock, i.e. the wall clock
    413          * that is subject to ntp updates and user alteration, so we will have to compenstate
    414          * for this by using RTTimeMilliTS together with the clock_gettime()/gettimeofday() call.
    415          * Joy, oh joy. */
    416         struct timespec     ts = {0,0};
     412        RTTHREAD hThreadSelf = RTThreadSelf();
     413#endif
     414        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
     415        rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex);
     416        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
     417        if (RT_UNLIKELY(rc))
     418        {
     419            AssertMsgFailed(("Failed to wait on event multi sem %p, rc=%d.\n", pThis, rc));
     420            ASMAtomicDecU32(&pThis->cWaiters);
     421            int rc2 = pthread_mutex_unlock(&pThis->Mutex);
     422            AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc2)); NOREF(rc2);
     423            return RTErrConvertFromErrno(rc);
     424        }
     425    }
     426}
     427
     428
     429/**
     430 * Implements the timed wait.
     431 *
     432 * @returns See RTSemEventMultiWaitEx
     433 * @param   pThis               The semaphore.
     434 * @param   fFlags              See RTSemEventMultiWaitEx.
     435 * @param   uTimeout            See RTSemEventMultiWaitEx.
     436 * @param   pSrcPos             The source position, can be NULL.
     437 */
     438static int rtSemEventMultiPosixWaitTimed(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, uint64_t uTimeout,
     439                                         PCRTLOCKVALSRCPOS pSrcPos)
     440{
     441    /*
     442     * Convert uTimeout to a relative value in nano seconds.
     443     */
     444    if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
     445        uTimeout = uTimeout < UINT64_MAX / UINT32_C(1000000) * UINT32_C(1000000)
     446                 ? uTimeout * UINT32_C(1000000)
     447                 : UINT64_MAX;
     448    if (uTimeout == UINT64_MAX) /* unofficial way of indicating an indefinite wait */
     449        return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
     450
     451    uint64_t uAbsTimeout = uTimeout;
     452    if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
     453    {
     454        uint64_t u64Now = RTTimeSystemNanoTS();
     455        uTimeout = uTimeout > u64Now ? uTimeout - u64Now : 0;
     456    }
     457
     458    if (uTimeout == 0)
     459        return rtSemEventMultiPosixWaitPoll(pThis);
     460
     461    /*
     462     * Get current time and calc end of deadline relative to real time.
     463     */
     464    struct timespec     ts = {0,0};
     465    if (!pThis->fMonotonicClock)
     466    {
    417467#ifdef RT_OS_DARWIN
    418         struct timeval      tv = {0,0};
     468        struct timeval  tv = {0,0};
    419469        gettimeofday(&tv, NULL);
    420470        ts.tv_sec = tv.tv_sec;
     
    423473        clock_gettime(CLOCK_REALTIME, &ts);
    424474#endif
    425         if (cMillies != 0)
    426         {
    427             ts.tv_nsec += (cMillies % 1000) * 1000000;
    428             ts.tv_sec  += cMillies / 1000;
    429             if (ts.tv_nsec >= 1000000000)
    430             {
    431                 ts.tv_nsec -= 1000000000;
    432                 ts.tv_sec++;
    433             }
    434         }
    435 
    436         /* take mutex */
    437         int rc = pthread_mutex_lock(&pThis->Mutex);
    438         if (rc)
    439         {
    440             AssertMsg(rc == ETIMEDOUT, ("Failed to lock event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
    441             return RTErrConvertFromErrno(rc);
    442         }
    443         ASMAtomicIncU32(&pThis->cWaiters);
    444 
    445         for (;;)
    446         {
    447             /* check state. */
    448             if (pThis->u32State == EVENTMULTI_STATE_SIGNALED)
     475        struct timespec tsAdd;
     476        tsAdd.tv_nsec = uTimeout % UINT32_C(1000000000);
     477        tsAdd.tv_sec  = uTimeout / UINT32_C(1000000000);
     478        if (   sizeof(ts.tv_sec) < sizeof(uint64_t)
     479            && (   uTimeout > UINT64_C(1000000000) * UINT32_MAX
     480                || (uint64_t)ts.tv_sec + tsAdd.tv_sec >= UINT32_MAX) )
     481            return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
     482
     483        ts.tv_sec  += tsAdd.tv_sec;
     484        ts.tv_nsec += tsAdd.tv_nsec;
     485        if (ts.tv_nsec >= 1000000000)
     486        {
     487            ts.tv_nsec -= 1000000000;
     488            ts.tv_sec++;
     489        }
     490        /* Note! No need to complete uAbsTimeout for RTSEMWAIT_FLAGS_RELATIVE in this path. */
     491    }
     492    else
     493    {
     494        /* ASSUMES RTTimeSystemNanoTS() == RTTimeNanoTS() == clock_gettime(CLOCK_MONOTONIC). */
     495        if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
     496            uAbsTimeout += RTTimeSystemNanoTS();
     497        if (   sizeof(ts.tv_sec) < sizeof(uint64_t)
     498            && uAbsTimeout > UINT64_C(1000000000) * UINT32_MAX)
     499            return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
     500        ts.tv_nsec = uAbsTimeout % UINT32_C(1000000000);
     501        ts.tv_sec  = uAbsTimeout / UINT32_C(1000000000);
     502    }
     503
     504    /*
     505     * To business!
     506     */
     507    /* take mutex */
     508    int rc = pthread_mutex_lock(&pThis->Mutex);
     509    AssertMsgReturn(rc == 0, ("rc=%d pThis=%p\n", rc, pThis), RTErrConvertFromErrno(rc)); NOREF(rc);
     510    ASMAtomicIncU32(&pThis->cWaiters);
     511
     512    for (;;)
     513    {
     514        /* check state. */
     515        uint32_t const u32State = pThis->u32State;
     516        if (u32State != EVENTMULTI_STATE_NOT_SIGNALED)
     517        {
     518            ASMAtomicDecU32(&pThis->cWaiters);
     519            rc = pthread_mutex_unlock(&pThis->Mutex);
     520            AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc));
     521            return u32State == EVENTMULTI_STATE_SIGNALED
     522                 ? VINF_SUCCESS
     523                 : VERR_SEM_DESTROYED;
     524        }
     525
     526        /* wait */
     527#ifdef RTSEMEVENTMULTI_STRICT
     528        RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     529        if (pThis->fEverHadSignallers)
     530        {
     531            rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     532                                                       uTimeout / UINT32_C(1000000), RTTHREADSTATE_EVENT_MULTI, true);
     533            if (RT_FAILURE(rc))
    449534            {
    450535                ASMAtomicDecU32(&pThis->cWaiters);
    451                 rc = pthread_mutex_unlock(&pThis->Mutex);
    452                 AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
    453                 return VINF_SUCCESS;
     536                pthread_mutex_unlock(&pThis->Mutex);
     537                return rc;
    454538            }
    455             if (pThis->u32State == EVENTMULTI_STATE_UNINITIALIZED)
    456             {
    457                 rc = pthread_mutex_unlock(&pThis->Mutex);
    458                 AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
    459                 return VERR_SEM_DESTROYED;
    460             }
    461 
    462             /* we're done if the timeout is 0. */
    463             if (!cMillies)
    464             {
    465                 ASMAtomicDecU32(&pThis->cWaiters);
    466                 rc = pthread_mutex_unlock(&pThis->Mutex);
    467                 return VERR_TIMEOUT;
    468             }
    469 
    470             /* wait */
    471 #ifdef RTSEMEVENTMULTI_STRICT
    472             RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
    473             if (pThis->fEverHadSignallers)
    474             {
    475                 rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
    476                                                            cMillies, RTTHREADSTATE_EVENT_MULTI, true);
    477                 if (RT_FAILURE(rc))
    478                 {
    479                     ASMAtomicDecU32(&pThis->cWaiters);
    480                     pthread_mutex_unlock(&pThis->Mutex);
    481                     return rc;
    482                 }
    483             }
     539        }
    484540#else
    485             RTTHREAD hThreadSelf = RTThreadSelf();
    486 #endif
    487             RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
    488             rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts);
    489             RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
    490             if (rc && (rc != EINTR || !fAutoResume)) /* according to SuS this function shall not return EINTR, but linux man page says differently. */
    491             {
    492                 AssertMsg(rc == ETIMEDOUT, ("Failed to wait on event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
    493                 ASMAtomicDecU32(&pThis->cWaiters);
    494                 int rc2 = pthread_mutex_unlock(&pThis->Mutex);
    495                 AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc2)); NOREF(rc2);
    496                 return RTErrConvertFromErrno(rc);
    497             }
    498         }
    499     }
    500 }
    501 
    502 
    503 RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
    504 {
    505     int rc = rtSemEventMultiWait(hEventMultiSem, cMillies, true);
    506     Assert(rc != VERR_INTERRUPTED);
    507     return rc;
    508 }
    509 
    510 
    511 RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
    512 {
    513     return rtSemEventMultiWait(hEventMultiSem, cMillies, false);
     541        RTTHREAD hThreadSelf = RTThreadSelf();
     542#endif
     543        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
     544        rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts);
     545        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
     546        if (    rc
     547            && (   rc != EINTR  /* according to SuS this function shall not return EINTR, but linux man page says differently. */
     548                || (fFlags & RTSEMWAIT_FLAGS_NORESUME)) )
     549        {
     550            AssertMsg(rc == ETIMEDOUT, ("Failed to wait on event multi sem %p, rc=%d.\n", pThis, rc));
     551            ASMAtomicDecU32(&pThis->cWaiters);
     552            int rc2 = pthread_mutex_unlock(&pThis->Mutex);
     553            AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc2)); NOREF(rc2);
     554            return RTErrConvertFromErrno(rc);
     555        }
     556
     557        /* check the absolute deadline. */
     558    }
     559}
     560
     561
     562DECLINLINE(int) rtSemEventMultiPosixWait(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     563                                         PCRTLOCKVALSRCPOS pSrcPos)
     564{
     565    /*
     566     * Validate input.
     567     */
     568    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     569    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     570    uint32_t u32 = pThis->u32State;
     571    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
     572    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
     573
     574    /*
     575     * Optimize the case where the event is signalled.
     576     */
     577    if (ASMAtomicUoReadU32(&pThis->u32State) == EVENTMULTI_STATE_SIGNALED)
     578    {
     579        int rc = rtSemEventMultiPosixWaitPoll(pThis);
     580        if (RT_LIKELY(rc != VERR_TIMEOUT))
     581            return rc;
     582    }
     583
     584    /*
     585     * Indefinite or timed wait?
     586     */
     587    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
     588        return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
     589    return rtSemEventMultiPosixWaitTimed(pThis, fFlags, uTimeout, pSrcPos);
     590}
     591
     592
     593#undef RTSemEventMultiWaitEx
     594RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
     595{
     596#ifndef RTSEMEVENT_STRICT
     597    return rtSemEventMultiPosixWait(hEventMultiSem, fFlags, uTimeout, NULL);
     598#else
     599    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
     600    return rtSemEventMultiPosixWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
     601#endif
     602}
     603
     604
     605RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     606                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
     607{
     608    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
     609    return rtSemEventMultiPosixWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
    514610}
    515611
  • trunk/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp

    r32949 r32966  
    5353
    5454    uint64_t u64 = RTTimeSystemMilliTS();
    55     RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT, rcCheck);
     55    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT);
    5656    u64 = RTTimeSystemMilliTS() - u64;
    5757    RTTEST_CHECK_MSG(g_hTest, u64 < 1500 && u64 > 950, (g_hTest, "u64=%llu\n", u64));
    5858
    59     RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS, rcCheck);
     59    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS);
    6060    return VINF_SUCCESS;
    6161}
     
    6565{
    6666    RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser;
    67     RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS, rcCheck);
     67    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
    6868    return VINF_SUCCESS;
    6969}
     
    246246int main(int argc, char **argv)
    247247{
    248     RTEXITCODE rcExit = RTTestInitAndCreate("tstSemEventMulti", &g_hTest);
     248    RTEXITCODE rcExit = RTTestInitAndCreate("tstRTSemEventMulti", &g_hTest);
    249249    if (rcExit != RTEXITCODE_SUCCESS)
    250250        return rcExit;
Note: See TracChangeset for help on using the changeset viewer.

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