VirtualBox

Changeset 25654 in vbox


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

semeventmulti-win.cpp: lock validation support.

File:
1 edited

Legend:

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

    r25640 r25654  
    22/** @file
    33 * IPRT - Multiple Release Event Semaphore, Windows.
     4 *
     5 * @remarks This file is identical to semevent-win.cpp except for the 2nd
     6 *          CreateEvent parameter, the reset function and the "Multi" infix.
    47 */
    58
    69/*
    7  * Copyright (C) 2006-2009 Sun Microsystems, Inc.
     10 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    811 *
    912 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3740
    3841#include <iprt/semaphore.h>
    39 #include <iprt/thread.h>
     42#include "internal/iprt.h"
     43
     44#include <iprt/asm.h>
    4045#include <iprt/assert.h>
    4146#include <iprt/err.h>
     47#include <iprt/lockvalidator.h>
     48#include <iprt/mem.h>
     49#include <iprt/thread.h>
     50#include "internal/magics.h"
    4251#include "internal/strict.h"
    4352
     
    4655*   Defined Constants And Macros                                               *
    4756*******************************************************************************/
    48 /** Converts semaphore to win32 handle. */
    49 #define SEM2HND(Sem) ((HANDLE)(uintptr_t)Sem)
     57struct RTSEMEVENTMULTIINTERNAL
     58{
     59    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
     60    uint32_t            u32Magic;
     61    /** The event handle. */
     62    HANDLE              hev;
     63#ifdef RTSEMEVENT_STRICT
     64    /** Signallers. */
     65    RTLOCKVALRECSHRD    Signallers;
     66    /** Indicates that lock validation should be performed. */
     67    bool volatile       fEverHadSignallers;
     68#endif
     69};
    5070
    5171
     
    5777RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
    5878{
     79    struct RTSEMEVENTMULTIINTERNAL *pThis = (struct RTSEMEVENTMULTIINTERNAL *)RTMemAlloc(sizeof(*pThis));
     80    if (!pThis)
     81        return VERR_NO_MEMORY;
     82
    5983    /*
    6084     * Create the semaphore.
    6185     * (Manual reset, not signaled, private event object.)
    6286     */
    63     HANDLE hev = CreateEvent(NULL, TRUE, FALSE, NULL);
    64     if (hev)
    65     {
    66         *pEventMultiSem = (RTSEMEVENTMULTI)(void *)hev;
     87    pThis->hev = CreateEvent(NULL, TRUE, FALSE, NULL);
     88    if (pThis->hev != NULL) /* not INVALID_HANDLE_VALUE */
     89    {
     90        pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
     91#ifdef RTSEMEVENT_STRICT
     92        RTLockValidatorRecSharedInit(&pThis->Signallers,
     93                                     NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,
     94                                     "RTSemEvent", pThis, true /*fSignaller*/);
     95        pThis->fEverHadSignallers = false;
     96#endif
     97
     98        *pEventMultiSem = pThis;
    6799        return VINF_SUCCESS;
    68100    }
    69     return RTErrConvertFromWin32(GetLastError());
     101
     102    DWORD dwErr = GetLastError();
     103    RTMemFree(pThis);
     104    return RTErrConvertFromWin32(dwErr);
    70105}
    71106
     
    73108RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
    74109{
    75     /*
    76      * Close semaphore handle.
    77      */
    78     if (CloseHandle(SEM2HND(EventMultiSem)))
     110    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     111    if (pThis == NIL_RTSEMEVENT)        /* don't bitch */
     112        return VERR_INVALID_HANDLE;
     113    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     114    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
     115
     116    /*
     117     * Invalidate the handle and close the semaphore.
     118     */
     119    int rc = VINF_SUCCESS;
     120    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC, RTSEMEVENTMULTI_MAGIC), VERR_INVALID_HANDLE);
     121    if (CloseHandle(pThis->hev))
     122    {
     123#ifdef RTSEMEVENT_STRICT
     124        RTLockValidatorRecSharedDelete(&pThis->Signallers);
     125#endif
     126        RTMemFree(pThis);
     127    }
     128    else
     129    {
     130        DWORD dwErr = GetLastError();
     131        rc = RTErrConvertFromWin32(dwErr);
     132        AssertMsgFailed(("Destroy EventMultiSem %p failed, lasterr=%u (%Rrc)\n", pThis, dwErr, rc));
     133        /* Leak it. */
     134    }
     135
     136    return rc;
     137}
     138
     139
     140RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
     141{
     142    /*
     143     * Validate input.
     144     */
     145    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     146    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     147    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
     148
     149#ifdef RTSEMEVENT_STRICT
     150    if (pThis->fEverHadSignallers)
     151    {
     152        int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD);
     153        if (RT_FAILURE(rc9))
     154            return rc9;
     155    }
     156#endif
     157
     158    /*
     159     * Signal the object.
     160     */
     161    if (SetEvent(pThis->hev))
    79162        return VINF_SUCCESS;
    80     AssertMsgFailed(("Destroy EventMultiSem %p failed, lasterr=%d\n", EventMultiSem, GetLastError()));
    81     return RTErrConvertFromWin32(GetLastError());
    82 }
    83 
    84 
    85 RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
    86 {
    87     /*
    88      * Signal the object.
    89      */
    90     if (SetEvent(SEM2HND(EventMultiSem)))
     163    DWORD dwErr = GetLastError();
     164    AssertMsgFailed(("Signaling EventMultiSem %p failed, lasterr=%d\n", pThis, dwErr));
     165    return RTErrConvertFromWin32(dwErr);
     166}
     167
     168
     169RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
     170{
     171    /*
     172     * Validate input.
     173     */
     174    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     175    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     176    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
     177
     178    /*
     179     * Reset the object.
     180     */
     181    if (ResetEvent(pThis->hev))
    91182        return VINF_SUCCESS;
    92     AssertMsgFailed(("Signaling EventMultiSem %p failed, lasterr=%d\n", EventMultiSem, GetLastError()));
    93     return RTErrConvertFromWin32(GetLastError());
    94 }
    95 
    96 
    97 RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
    98 {
    99     /*
    100      * Reset the object.
    101      */
    102     if (ResetEvent(SEM2HND(EventMultiSem)))
    103         return VINF_SUCCESS;
    104     AssertMsgFailed(("Resetting EventMultiSem %p failed, lasterr=%d\n", EventMultiSem, GetLastError()));
    105     return RTErrConvertFromWin32(GetLastError());
     183    DWORD dwErr = GetLastError();
     184    AssertMsgFailed(("Resetting EventMultiSem %p failed, lasterr=%d\n", pThis, dwErr));
     185    return RTErrConvertFromWin32(dwErr);
    106186}
    107187
     
    109189RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
    110190{
     191    PCRTLOCKVALSRCPOS pSrcPos = NULL;
     192
     193    /*
     194     * Validate input.
     195     */
     196    struct RTSEMEVENTMULTIINTERNAL *pThis = EventMultiSem;
     197    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     198    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
     199
    111200    /*
    112201     * Wait for condition.
    113202     */
    114     int rc = WaitForSingleObjectEx(SEM2HND(EventMultiSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE);
     203#ifdef RTSEMEVENT_STRICT
     204    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     205    if (pThis->fEverHadSignallers)
     206    {
     207        int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     208                                                        RTTHREADSTATE_EVENT_MULTI, true);
     209        if (RT_FAILURE(rc9))
     210            return rc9;
     211    }
     212#else
     213    RTTHREAD hThreadSelf = RTThreadSelf();
     214#endif
     215    RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
     216    DWORD rc = WaitForSingleObjectEx(pThis->hev,
     217                                     cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
     218                                     TRUE /*fAlertable*/);
     219    RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
    115220    switch (rc)
    116221    {
     
    120225        case WAIT_ABANDONED:        return VERR_SEM_OWNER_DIED;
    121226        default:
     227            AssertMsgFailed(("%u\n", rc));
     228        case WAIT_FAILED:
    122229        {
    123             AssertMsgFailed(("Wait on EventMultiSem %p failed, rc=%d lasterr=%d\n", EventMultiSem, rc, GetLastError()));
     230            AssertMsgFailed(("Wait on EventMultiSem %p failed, rc=%d lasterr=%d\n", pThis, rc, GetLastError()));
    124231            int rc2 = RTErrConvertFromWin32(GetLastError());
    125232            if (rc2)
     
    135242RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
    136243{
    137     /** @todo implement RTSemEventMultiSetSignaller on Windows */
     244#ifdef RTSEMEVENT_STRICT
     245    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     246    AssertPtrReturnVoid(pThis);
     247    AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC);
     248
     249    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
     250    RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
     251#endif
    138252}
    139253
     
    141255RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
    142256{
     257#ifdef RTSEMEVENT_STRICT
     258    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     259    AssertPtrReturnVoid(pThis);
     260    AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC);
     261
     262    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
     263    RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
     264#endif
    143265}
    144266
     
    146268RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
    147269{
    148 }
    149 
     270#ifdef RTSEMEVENT_STRICT
     271    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
     272    AssertPtrReturnVoid(pThis);
     273    AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC);
     274
     275    RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
     276#endif
     277}
     278
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