VirtualBox

Changeset 25382 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Dec 15, 2009 12:30:34 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56006
Message:

semmutex-win.cpp: Use a structure instead of storing the native handle as the IPRT handle. This allows for the same parameter checking as elsewhere as well as lock validation.

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

Legend:

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

    r25381 r25382  
    3737
    3838#include <iprt/semaphore.h>
     39#include "internal/iprt.h"
     40
     41#include <iprt/assert.h>
     42#include <iprt/asm.h>
     43#include <iprt/err.h>
     44#include <iprt/lockvalidator.h>
     45#include <iprt/mem.h>
    3946#include <iprt/thread.h>
    40 #include <iprt/assert.h>
    41 #include <iprt/err.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)
     54/** Posix internal representation of a Mutex semaphore. */
     55struct RTSEMMUTEXINTERNAL
     56{
     57    /** Magic value (RTSEMMUTEX_MAGIC). */
     58    uint32_t            u32Magic;
     59    /** The mutex handle. */
     60    HANDLE              hMtx;
     61#ifdef RTSEMMUTEX_STRICT
     62    /** Lock validator record associated with this mutex. */
     63    RTLOCKVALIDATORREC  ValidatorRec;
     64#endif
     65};
    5066
    5167
     
    5773RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
    5874{
     75    int rc;
     76
    5977    /*
    6078     * Create the semaphore.
    6179     */
    62     HANDLE hmtx = CreateMutex(NULL, FALSE, NULL);
    63     if (hmtx)
     80    HANDLE hMtx = CreateMutex(NULL, FALSE, NULL);
     81    if (hMtx)
    6482    {
    65         *pMutexSem = (RTSEMMUTEX)(void *)hmtx;
     83        RTSEMMUTEXINTERNAL *pThis = (RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(*pThis));
     84        if (pThis)
     85        {
     86            pThis->u32Magic = RTSEMMUTEX_MAGIC;
     87            pThis->hMtx = hMtx;
     88#ifdef RTSEMMUTEX_STRICT
     89            RTLockValidatorInit(&pThis->ValidatorRec,  NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis);
     90#endif
     91            *pMutexSem = pThis;
     92            return VINF_SUCCESS;
     93        }
     94
     95        rc = VERR_NO_MEMORY;
     96    }
     97    else
     98        rc = RTErrConvertFromWin32(GetLastError());
     99    return rc;
     100}
     101
     102
     103RTDECL(int)  RTSemMutexDestroy(RTSEMMUTEX MutexSem)
     104{
     105    /*
     106     * Validate.
     107     */
     108    RTSEMMUTEXINTERNAL *pThis = MutexSem;
     109    if (pThis == NIL_RTSEMMUTEX)
    66110        return VINF_SUCCESS;
     111    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     112    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     113
     114    /*
     115     * Close semaphore handle.
     116     */
     117    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
     118    HANDLE hMtx = pThis->hMtx;
     119    ASMAtomicWritePtr((void * volatile *)&pThis->hMtx, (void *)INVALID_HANDLE_VALUE);
     120
     121    int rc = VINF_SUCCESS;
     122    if (!CloseHandle(hMtx))
     123    {
     124        rc = RTErrConvertFromWin32(GetLastError());
     125        AssertMsgFailed(("%p rc=%d lasterr=%d\n", pThis->hMtx, rc, GetLastError()));
    67126    }
    68127
    69     return RTErrConvertFromWin32(GetLastError());
    70 }
    71 
    72 
    73 RTDECL(int)  RTSemMutexDestroy(RTSEMMUTEX MutexSem)
    74 {
    75     /*
    76      * Close semaphore handle.
    77      */
    78     if (CloseHandle(SEM2HND(MutexSem)))
    79         return VINF_SUCCESS;
    80     AssertMsgFailed(("Destroy MutexSem %p failed, lasterr=%d\n", MutexSem, GetLastError()));
    81     return RTErrConvertFromWin32(GetLastError());
    82 }
    83 
    84 
    85 RTDECL(int)  RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
    86 {
     128#ifdef RTSEMMUTEX_STRICT
     129    RTLockValidatorDelete(&pThis->ValidatorRec);
     130#endif
     131    RTMemFree(pThis);
     132    return rc;
     133}
     134
     135
     136/**
     137 * Internal worker for RTSemMutexRequestNoResume and it's debug companion.
     138 *
     139 * @returns Same as RTSEmMutexRequestNoResume
     140 * @param   MutexSem                    The mutex handle.
     141 * @param   cMillies                    The number of milliseconds to wait.
     142 * @param   TSEMMUTEX_STRICT_POS_DECL   The source position of the caller.
     143 */
     144DECL_FORCE_INLINE(int) rtSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies, RTSEMMUTEX_STRICT_POS_DECL)
     145{
     146    /*
     147     * Validate.
     148     */
     149    RTSEMMUTEXINTERNAL *pThis = MutexSem;
     150    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     151    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     152
     153#ifdef RTSEMMUTEX_STRICT
     154    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     155    RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS);
     156#else
     157    RTTHREAD hThreadSelf = RTThreadSelf();
     158#endif
     159
    87160    /*
    88161     * Lock mutex semaphore.
    89162     */
    90     int rc = WaitForSingleObjectEx(SEM2HND(MutexSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE);
     163    if (cMillies > 0)
     164        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec));
     165    int rc = WaitForSingleObjectEx(pThis->hMtx,
     166                                   cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
     167                                   TRUE /*bAlertable*/);
     168    RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
    91169    switch (rc)
    92170    {
    93171        case WAIT_OBJECT_0:
    94         {
    95 #ifdef RTSEMMUTEX_STRICT
    96             RTTHREAD Thread = RTThreadSelf();
    97             if (Thread != NIL_RTTHREAD)
    98                 RTThreadWriteLockInc(Thread);
     172#ifdef RTSEMMUTEX_STRICT
     173            RTThreadWriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS));
    99174#endif
    100175            return VINF_SUCCESS;
    101         }
    102176
    103177        case WAIT_TIMEOUT:          return VERR_TIMEOUT;
     
    118192
    119193
    120 RTDECL(int)  RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
    121 {
     194RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
     195{
     196#ifndef RTSEMMUTEX_STRICT
     197    return rtSemMutexRequestNoResume(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
     198#else
     199    return RTSemMutexRequestNoResumeDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
     200#endif
     201}
     202
     203
     204RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     205{
     206#ifdef RTSEMMUTEX_STRICT
     207    return rtSemMutexRequestNoResume(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
     208#else
    122209    return RTSemMutexRequestNoResume(MutexSem, cMillies);
    123 }
    124 
    125 
    126 RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem)
    127 {
     210#endif
     211}
     212
     213
     214RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
     215{
     216    /*
     217     * Validate.
     218     */
     219    RTSEMMUTEXINTERNAL *pThis = MutexSem;
     220    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     221    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     222
    128223    /*
    129224     * Unlock mutex semaphore.
    130225     */
    131226#ifdef RTSEMMUTEX_STRICT
    132     RTTHREAD Thread = RTThreadSelf();
    133     if (Thread != NIL_RTTHREAD)
    134         RTThreadWriteLockDec(Thread);
    135 #endif
    136     if (ReleaseMutex(SEM2HND(MutexSem)))
     227    if (   pThis->ValidatorRec.hThread != NIL_RTTHREAD
     228        && pThis->ValidatorRec.hThread == RTThreadSelf())
     229        RTThreadWriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec));
     230    else
     231        AssertMsgFailed(("%p hThread=%RTthrd\n", pThis, pThis->ValidatorRec.hThread));
     232#endif
     233    if (ReleaseMutex(pThis->hMtx))
    137234        return VINF_SUCCESS;
    138 
    139 #ifdef RTSEMMUTEX_STRICT
    140     if (Thread != NIL_RTTHREAD)
    141         RTThreadWriteLockInc(Thread);
    142 #endif
    143     AssertMsgFailed(("Release MutexSem %p failed, lasterr=%d\n", MutexSem, GetLastError()));
    144     return RTErrConvertFromWin32(GetLastError());
    145 }
    146 
     235    int rc = RTErrConvertFromWin32(GetLastError());
     236    AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError()));
     237    return rc;
     238}
     239
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r25059 r25382  
    9292        tstSems \
    9393        tstSemEvent \
     94        tstSemMutex \
    9495        tstSemPingPong \
    9596        tstRTStrCache \
     
    124125        tstInlineAsmPIC \
    125126        tstInlineAsmPIC3 \
    126         tstSemMutex \
    127127        tstSemRW
    128128PROGRAMS.l4 += \
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