VirtualBox

Changeset 25653 in vbox for trunk/src/VBox/Runtime/r3


Ignore:
Timestamp:
Jan 5, 2010 3:22:29 PM (15 years ago)
Author:
vboxsync
Message:

semevent-win.cpp: lock validation support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/semevent-win.cpp

    r25640 r25653  
    3737
    3838#include <iprt/semaphore.h>
    39 #include <iprt/thread.h>
     39#include "internal/iprt.h"
     40
     41#include <iprt/asm.h>
    4042#include <iprt/assert.h>
    4143#include <iprt/err.h>
     44#include <iprt/lockvalidator.h>
     45#include <iprt/mem.h>
     46#include <iprt/thread.h>
     47#include "internal/magics.h"
    4248#include "internal/strict.h"
    4349
     
    4652*   Defined Constants And Macros                                               *
    4753*******************************************************************************/
    48 /** Converts semaphore to win32 handle. */
    49 #define SEM2HND(Sem) ((HANDLE)(uintptr_t)Sem)
     54struct RTSEMEVENTINTERNAL
     55{
     56    /** Magic value (RTSEMEVENT_MAGIC). */
     57    uint32_t            u32Magic;
     58    /** The event handle. */
     59    HANDLE              hev;
     60#ifdef RTSEMEVENT_STRICT
     61    /** Signallers. */
     62    RTLOCKVALRECSHRD    Signallers;
     63    /** Indicates that lock validation should be performed. */
     64    bool volatile       fEverHadSignallers;
     65#endif
     66};
    5067
    5168
     
    5774RTDECL(int)   RTSemEventCreate(PRTSEMEVENT pEventSem)
    5875{
     76    struct RTSEMEVENTINTERNAL *pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(*pThis));
     77    if (!pThis)
     78        return VERR_NO_MEMORY;
     79
    5980    /*
    6081     * Create the semaphore.
    6182     * (Auto reset, not signaled, private event object.)
    6283     */
    63     HANDLE hev = CreateEvent(NULL, FALSE, FALSE, NULL);
    64     if (hev)
    65     {
    66         *pEventSem = (RTSEMEVENT)(void *)hev;
    67         Assert(*pEventSem != NIL_RTSEMEVENT);
     84    pThis->hev = CreateEvent(NULL, FALSE, FALSE, NULL);
     85    if (pThis->hev != NULL) /* not INVALID_HANDLE_VALUE */
     86    {
     87        pThis->u32Magic = RTSEMEVENT_MAGIC;
     88#ifdef RTSEMEVENT_STRICT
     89        RTLockValidatorRecSharedInit(&pThis->Signallers,
     90                                     NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,
     91                                     "RTSemEvent", pThis, true /*fSignaller*/);
     92        pThis->fEverHadSignallers = false;
     93#endif
     94
     95        *pEventSem = pThis;
    6896        return VINF_SUCCESS;
    6997    }
    70     return RTErrConvertFromWin32(GetLastError());
     98
     99    DWORD dwErr = GetLastError();
     100    RTMemFree(pThis);
     101    return RTErrConvertFromWin32(dwErr);
    71102}
    72103
     
    74105RTDECL(int)   RTSemEventDestroy(RTSEMEVENT EventSem)
    75106{
    76     if (EventSem == NIL_RTSEMEVENT)     /* don't bitch */
     107    struct RTSEMEVENTINTERNAL *pThis = EventSem;
     108    if (pThis == NIL_RTSEMEVENT)        /* don't bitch */
    77109        return VERR_INVALID_HANDLE;
    78 
    79     /*
    80      * Close semaphore handle.
    81      */
    82     if (CloseHandle(SEM2HND(EventSem)))
    83         return VINF_SUCCESS;
    84     AssertMsgFailed(("Destroy EventSem %p failed, lasterr=%d\n", EventSem, GetLastError()));
    85     return RTErrConvertFromWin32(GetLastError());
     110    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     111    AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
     112
     113    /*
     114     * Invalidate the handle and close the semaphore.
     115     */
     116    int rc = VINF_SUCCESS;
     117    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMEVENT_MAGIC, RTSEMEVENT_MAGIC), VERR_INVALID_HANDLE);
     118    if (CloseHandle(pThis->hev))
     119    {
     120#ifdef RTSEMEVENT_STRICT
     121        RTLockValidatorRecSharedDelete(&pThis->Signallers);
     122#endif
     123        RTMemFree(pThis);
     124    }
     125    else
     126    {
     127        DWORD dwErr = GetLastError();
     128        rc = RTErrConvertFromWin32(dwErr);
     129        AssertMsgFailed(("Destroy EventSem %p failed, lasterr=%u (%Rrc)\n", pThis, dwErr, rc));
     130        /* Leak it. */
     131    }
     132
     133    return rc;
    86134}
    87135
     
    89137RTDECL(int)   RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
    90138{
     139    PCRTLOCKVALSRCPOS pSrcPos = NULL;
     140
     141    /*
     142     * Validate input.
     143     */
     144    struct RTSEMEVENTINTERNAL *pThis = EventSem;
     145    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     146    AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
     147
    91148    /*
    92149     * Wait for condition.
    93150     */
    94     int rc = WaitForSingleObjectEx(SEM2HND(EventSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE);
     151#ifdef RTSEMEVENT_STRICT
     152    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     153    if (pThis->fEverHadSignallers)
     154    {
     155        int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     156                                                        RTTHREADSTATE_EVENT, true);
     157        if (RT_FAILURE(rc9))
     158            return rc9;
     159    }
     160#else
     161    RTTHREAD hThreadSelf = RTThreadSelf();
     162#endif
     163    RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true);
     164    DWORD rc = WaitForSingleObjectEx(pThis->hev,
     165                                     cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
     166                                     TRUE /*fAlertable*/);
     167    RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT);
    95168    switch (rc)
    96169    {
     
    100173        case WAIT_ABANDONED:        return VERR_SEM_OWNER_DIED;
    101174        default:
     175            AssertMsgFailed(("%u\n", rc));
     176        case WAIT_FAILED:
    102177        {
    103178            AssertMsgFailed(("Wait on EventSem %p failed, rc=%d lasterr=%d\n", EventSem, rc, GetLastError()));
     
    116191{
    117192    /*
     193     * Validate input.
     194     */
     195    struct RTSEMEVENTINTERNAL *pThis = EventSem;
     196    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     197    AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
     198
     199#ifdef RTSEMEVENT_STRICT
     200    if (pThis->fEverHadSignallers)
     201    {
     202        int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD);
     203        if (RT_FAILURE(rc9))
     204            return rc9;
     205    }
     206#endif
     207
     208    /*
    118209     * Signal the object.
    119210     */
    120     if (SetEvent(SEM2HND(EventSem)))
     211    if (SetEvent(pThis->hev))
    121212        return VINF_SUCCESS;
    122     AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", EventSem, GetLastError()));
    123     return RTErrConvertFromWin32(GetLastError());
     213    DWORD dwErr = GetLastError();
     214    AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", pThis, dwErr));
     215    return RTErrConvertFromWin32(dwErr);
    124216}
    125217
     
    127219RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
    128220{
    129 /** @todo implement RTSemEventSetSignaller and friends for NT. */
     221#ifdef RTSEMEVENT_STRICT
     222    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
     223    AssertPtrReturnVoid(pThis);
     224    AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
     225
     226    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
     227    RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
     228#endif
    130229}
    131230
     
    133232RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
    134233{
    135 
     234#ifdef RTSEMEVENT_STRICT
     235    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
     236    AssertPtrReturnVoid(pThis);
     237    AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
     238
     239    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
     240    RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
     241#endif
    136242}
    137243
     
    139245RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
    140246{
    141 
    142 }
    143 
     247#ifdef RTSEMEVENT_STRICT
     248    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
     249    AssertPtrReturnVoid(pThis);
     250    AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
     251
     252    RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
     253#endif
     254}
     255
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