VirtualBox

Changeset 25640 in vbox for trunk/src/VBox/Runtime/r3/posix


Ignore:
Timestamp:
Jan 4, 2010 4:44:23 PM (15 years ago)
Author:
vboxsync
Message:

iprt: Added RTSemEventMulti[Set|Add|Remove]Signaller.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp

    r25636 r25640  
    3333*******************************************************************************/
    3434#include <iprt/semaphore.h>
     35#include "internal/iprt.h"
     36
     37#include <iprt/asm.h>
    3538#include <iprt/assert.h>
    36 #include <iprt/alloc.h>
    37 #include <iprt/asm.h>
    3839#include <iprt/err.h>
     40#include <iprt/lockvalidator.h>
     41#include <iprt/mem.h>
     42
     43#include "internal/strict.h"
    3944
    4045#include <errno.h>
     
    6166    /** Number of waiters. */
    6267    volatile uint32_t   cWaiters;
     68#ifdef RTSEMEVENTMULTI_STRICT
     69    /** Signallers. */
     70    RTLOCKVALRECSHRD    Signallers;
     71    /** Indicates that lock validation should be performed. */
     72    bool volatile       fEverHadSignallers;
     73#endif
    6374};
    6475
     
    7384/** @} */
    7485
    75 
    76 
    77 /**
    78  * Validate an event multi semaphore handle passed to one of the interface.
    79  *
    80  * @returns true if valid.
    81  * @returns false if invalid.
    82  * @param   pThis    Pointer to the event semaphore to validate.
    83  */
    84 inline bool rtsemEventMultiValid(struct RTSEMEVENTMULTIINTERNAL *pThis)
    85 {
    86     if ((uintptr_t)pThis < 0x10000)
    87         return false;
    88 
    89     uint32_t    u32 = pThis->u32State; /* this is volatile, so a explicit read like this is needed. */
    90     if (    u32 != EVENTMULTI_STATE_NOT_SIGNALED
    91         &&  u32 != EVENTMULTI_STATE_SIGNALED)
    92         return false;
    93 
    94     return true;
    95 }
    9686
    9787
     
    131121                        ASMAtomicXchgU32(&pThis->u32State, EVENTMULTI_STATE_NOT_SIGNALED);
    132122                        ASMAtomicXchgU32(&pThis->cWaiters, 0);
     123#ifdef RTSEMEVENTMULTI_STRICT
     124                        RTLockValidatorRecSharedInit(&pThis->Signallers,
     125                                                     NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,
     126                                                     "RTSemEvent", pThis, true /*fSignaller*/);
     127                        pThis->fEverHadSignallers = false;
     128#endif
    133129
    134130                        *pEventMultiSem = pThis;
     
    159155     * Validate handle.
    160156     */
    161     if (!rtsemEventMultiValid(EventMultiSem))
    162     {
    163         AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem));
    164         return VERR_INVALID_HANDLE;
    165     }
     157    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     158    if (pThis == NIL_RTSEMEVENTMULTI)
     159        return VINF_SUCCESS;
     160    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     161    uint32_t u32 = pThis->u32State;
     162    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
    166163
    167164    /*
    168165     * Abort all waiters forcing them to return failure.
    169166     */
    170     struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
    171167    int rc;
    172168    for (int i = 30; i > 0; i--)
     
    205201     * Free the semaphore memory and be gone.
    206202     */
     203#ifdef RTSEMEVENTMULTI_STRICT
     204    RTLockValidatorRecSharedDelete(&pThis->Signallers);
     205#endif
    207206    RTMemFree(pThis);
    208207    return VINF_SUCCESS;
     
    215214     * Validate input.
    216215     */
    217     if (!rtsemEventMultiValid(EventMultiSem))
    218     {
    219         AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem));
    220         return VERR_INVALID_HANDLE;
    221     }
     216    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     217    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     218    uint32_t u32 = pThis->u32State;
     219    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
     220
     221#ifdef RTSEMEVENTMULTI_STRICT
     222    if (pThis->fEverHadSignallers)
     223    {
     224        int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD);
     225        if (RT_FAILURE(rc9))
     226            return rc9;
     227    }
     228#endif
    222229
    223230    /*
    224231     * Lock the mutex semaphore.
    225232     */
    226     struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
    227233    int rc = pthread_mutex_lock(&pThis->Mutex);
    228234    if (rc)
     
    268274     * Validate input.
    269275     */
    270     if (!rtsemEventMultiValid(EventMultiSem))
    271     {
    272         AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem));
    273         return VERR_INVALID_HANDLE;
    274     }
     276    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     277    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     278    uint32_t u32 = pThis->u32State;
     279    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
    275280
    276281    /*
    277282     * Lock the mutex semaphore.
    278283     */
    279     struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
    280284    int rc = pthread_mutex_lock(&pThis->Mutex);
    281285    if (rc)
     
    310314static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fAutoResume)
    311315{
     316    PCRTLOCKVALSRCPOS pSrcPos = NULL;
     317
    312318    /*
    313319     * Validate input.
    314320     */
    315     if (!rtsemEventMultiValid(EventMultiSem))
    316     {
    317         AssertMsgFailed(("Invalid handle %p!\n", EventMultiSem));
    318         return VERR_INVALID_HANDLE;
    319     }
     321    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     322    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     323    uint32_t u32 = pThis->u32State;
     324    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
    320325
    321326    /*
    322327     * Timed or indefinite wait?
    323328     */
    324     struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
    325329    if (cMillies == RT_INDEFINITE_WAIT)
    326330    {
     
    352356
    353357            /* wait */
     358#ifdef RTSEMEVENTMULTI_STRICT
     359            RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     360            if (pThis->fEverHadSignallers)
     361            {
     362                rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     363                                                           RTTHREADSTATE_EVENT_MULTI, true);
     364                if (RT_FAILURE(rc))
     365                {
     366                    ASMAtomicDecU32(&pThis->cWaiters);
     367                    pthread_mutex_unlock(&pThis->Mutex);
     368                    return rc;
     369                }
     370            }
     371#else
     372            RTTHREAD hThreadSelf = RTThreadSelf();
     373#endif
     374            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
    354375            rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex);
     376            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
    355377            if (rc)
    356378            {
     
    396418
    397419        /* take mutex */
    398 #ifdef RT_OS_DARWIN
    399420        int rc = pthread_mutex_lock(&pThis->Mutex);
    400 #else
    401         int rc = pthread_mutex_timedlock(&pThis->Mutex, &ts);
    402 #endif
    403421        if (rc)
    404422        {
     
    425443            }
    426444
     445            /* we're done if the timeout is 0. */
     446            if (!cMillies)
     447            {
     448                ASMAtomicDecU32(&pThis->cWaiters);
     449                rc = pthread_mutex_unlock(&pThis->Mutex);
     450                return VERR_SEM_BUSY;
     451            }
     452
    427453            /* wait */
     454#ifdef RTSEMEVENTMULTI_STRICT
     455            RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     456            if (pThis->fEverHadSignallers)
     457            {
     458                rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     459                                                           RTTHREADSTATE_EVENT_MULTI, true);
     460                if (RT_FAILURE(rc))
     461                {
     462                    ASMAtomicDecU32(&pThis->cWaiters);
     463                    pthread_mutex_unlock(&pThis->Mutex);
     464                    return rc;
     465                }
     466            }
     467#else
     468            RTTHREAD hThreadSelf = RTThreadSelf();
     469#endif
     470            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
    428471            rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts);
     472            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
    429473            if (rc && (rc != EINTR || !fAutoResume)) /* according to SuS this function shall not return EINTR, but linux man page says differently. */
    430474            {
     
    453497}
    454498
     499
     500RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
     501{
     502#ifdef RTSEMEVENTMULTI_STRICT
     503    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     504    AssertPtrReturnVoid(pThis);
     505    uint32_t u32 = pThis->u32State;
     506    AssertReturnVoid(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED);
     507
     508    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
     509    RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
     510#endif
     511}
     512
     513
     514RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
     515{
     516#ifdef RTSEMEVENTMULTI_STRICT
     517    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     518    AssertPtrReturnVoid(pThis);
     519    uint32_t u32 = pThis->u32State;
     520    AssertReturnVoid(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED);
     521
     522    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
     523    RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
     524#endif
     525}
     526
     527
     528RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
     529{
     530#ifdef RTSEMEVENTMULTI_STRICT
     531    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     532    AssertPtrReturnVoid(pThis);
     533    uint32_t u32 = pThis->u32State;
     534    AssertReturnVoid(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED);
     535
     536    RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
     537#endif
     538}
     539
Note: See TracChangeset for help on using the changeset viewer.

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