semmutex-win.cpp revision 47d9037afecc80d7a107338f0adfda45c1224fed
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync/* $Id$ */
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync/** @file
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * IPRT - Mutex Semaphores, Windows.
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync */
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync/*
aae8a6a38fd27661046ab1d06cb2cb5c096c40edvboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync *
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * available from http://www.virtualbox.org. This file is free software;
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * you can redistribute it and/or modify it under the terms of the GNU
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * General Public License (GPL) as published by the Free Software
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync *
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * The contents of this file may alternatively be used under the terms
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * of the Common Development and Distribution License Version 1.0
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * VirtualBox OSE distribution, in which case the provisions of the
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * CDDL are applicable instead of those of the GPL.
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync *
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync * You may elect to license modified versions of this file under the
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * terms and conditions of either the GPL or the CDDL or both.
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync *
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * additional information or have any questions.
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync */
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync/*******************************************************************************
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync* Header Files *
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync*******************************************************************************/
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#define LOG_GROUP RTLOGGROUP_SEMAPHORE
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <Windows.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <iprt/semaphore.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include "internal/iprt.h"
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#include <iprt/asm.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <iprt/assert.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <iprt/err.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <iprt/lockvalidator.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <iprt/mem.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include <iprt/thread.h>
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include "internal/magics.h"
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#include "internal/strict.h"
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync/*******************************************************************************
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync* Defined Constants And Macros *
1759f65b60e18f669f6d569aebd4fb7217ab414fvboxsync*******************************************************************************/
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync/** Posix internal representation of a Mutex semaphore. */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsyncstruct RTSEMMUTEXINTERNAL
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync{
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync /** Magic value (RTSEMMUTEX_MAGIC). */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync uint32_t u32Magic;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync /** Recursion count. */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync uint32_t volatile cRecursions;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync /** The owner thread. */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync RTNATIVETHREAD volatile hNativeOwner;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync /** The mutex handle. */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync HANDLE hMtx;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#ifdef RTSEMMUTEX_STRICT
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync /** Lock validator record associated with this mutex. */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync RTLOCKVALRECEXCL ValidatorRec;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#endif
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync};
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync/* Undefine debug mappings. */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#undef RTSemMutexRequest
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#undef RTSemMutexRequestNoResume
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsyncRTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync{
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync int rc;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync /*
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync * Create the semaphore.
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync */
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync HANDLE hMtx = CreateMutex(NULL, FALSE, NULL);
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync if (hMtx)
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync {
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync RTSEMMUTEXINTERNAL *pThis = (RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(*pThis));
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync if (pThis)
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync {
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync pThis->u32Magic = RTSEMMUTEX_MAGIC;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync pThis->hMtx = hMtx;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync pThis->hNativeOwner = NIL_RTNATIVETHREAD;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync pThis->cRecursions = 0;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync#ifdef RTSEMMUTEX_STRICT
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, pThis,
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync true /*fEnabled*/, "RTSemMutex");
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync#endif
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync *pMutexSem = pThis;
1759f65b60e18f669f6d569aebd4fb7217ab414fvboxsync return VINF_SUCCESS;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync }
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync rc = VERR_NO_MEMORY;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync }
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync else
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync rc = RTErrConvertFromWin32(GetLastError());
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync return rc;
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync}
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsyncRTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync{
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync /*
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync * Validate.
f6dd48677b626c383d1a91cba7688abb0945af7dvboxsync */
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync RTSEMMUTEXINTERNAL *pThis = MutexSem;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync if (pThis == NIL_RTSEMMUTEX)
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync return VINF_SUCCESS;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync /*
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * Close semaphore handle.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync HANDLE hMtx = pThis->hMtx;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync ASMAtomicWritePtr((void * volatile *)&pThis->hMtx, (void *)INVALID_HANDLE_VALUE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync int rc = VINF_SUCCESS;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (!CloseHandle(hMtx))
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync rc = RTErrConvertFromWin32(GetLastError());
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertMsgFailed(("%p rc=%d lasterr=%d\n", pThis->hMtx, rc, GetLastError()));
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync }
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#ifdef RTSEMMUTEX_STRICT
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTLockValidatorRecExclDelete(&pThis->ValidatorRec);
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync#endif
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTMemFree(pThis);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rc;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync}
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync/**
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * Internal worker for RTSemMutexRequestNoResume and it's debug companion.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync *
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * @returns Same as RTSEmMutexRequestNoResume
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * @param MutexSem The mutex handle.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * @param cMillies The number of milliseconds to wait.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * @param pSrcPos The source position of the caller.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsyncDECL_FORCE_INLINE(int) rtSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies, PCRTLOCKVALSRCPOS pSrcPos)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync{
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync /*
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * Validate.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTSEMMUTEXINTERNAL *pThis = MutexSem;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync /*
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * Check for recursive entry.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync RTNATIVETHREAD hNativeOwner;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync ASMAtomicReadHandle(&pThis->hNativeOwner, &hNativeOwner);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (hNativeOwner == hNativeSelf)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#ifdef RTSEMMUTEX_STRICT
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync int rc9 = RTLockValidatorRecExclRecursion(&pThis->ValidatorRec, pSrcPos);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (RT_FAILURE(rc9))
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rc9;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#endif
63a23b6d96aca4c8545d3c3e89cc454af7ba3da6vboxsync ASMAtomicIncU32(&pThis->cRecursions);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return VINF_SUCCESS;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync }
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync /*
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync * Lock mutex semaphore.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTTHREAD hThreadSelf = NIL_RTTHREAD;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (cMillies > 0)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#ifdef RTSEMMUTEX_STRICT
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync hThreadSelf = RTThreadSelfAutoAdopt();
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true,
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync cMillies, RTTHREADSTATE_MUTEX, true);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (RT_FAILURE(rc9))
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rc9;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#else
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync hThreadSelf = RTThreadSelf();
90ecd36a6e45ec33526541f68cf89c21ec578f83vboxsync RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, true);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#endif
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync }
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync DWORD rc = WaitForSingleObjectEx(pThis->hMtx,
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync TRUE /*fAlertable*/);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync switch (rc)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync case WAIT_OBJECT_0:
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#ifdef RTSEMMUTEX_STRICT
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTLockValidatorRecExclSetOwner(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#endif
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync ASMAtomicWriteHandle(&pThis->hNativeOwner, hNativeSelf);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync ASMAtomicWriteU32(&pThis->cRecursions, 1);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return VINF_SUCCESS;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync case WAIT_TIMEOUT: return VERR_TIMEOUT;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync case WAIT_IO_COMPLETION: return VERR_INTERRUPTED;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync default:
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertMsgFailed(("%u\n", rc));
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync case WAIT_FAILED:
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync int rc2 = RTErrConvertFromWin32(GetLastError());
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertMsgFailed(("Wait on MutexSem %p failed, rc=%d lasterr=%d\n", MutexSem, rc, GetLastError()));
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (rc2 != VINF_SUCCESS)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rc2;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertMsgFailed(("WaitForSingleObject(event) -> rc=%d while converted lasterr=%d\n", rc, rc2));
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return VERR_INTERNAL_ERROR;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync }
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync }
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync}
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsyncRTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync{
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#ifndef RTSEMMUTEX_STRICT
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rtSemMutexRequestNoResume(MutexSem, cMillies, NULL);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#else
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rtSemMutexRequestNoResume(MutexSem, cMillies, &SrcPos);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#endif
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync}
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsyncRTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync{
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return rtSemMutexRequestNoResume(MutexSem, cMillies, &SrcPos);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync}
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsyncRTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync{
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync /*
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * Validate.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTSEMMUTEXINTERNAL *pThis = MutexSem;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync /*
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync * Check ownership and recursions.
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync */
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync RTNATIVETHREAD hNativeOwner;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync ASMAtomicReadHandle(&pThis->hNativeOwner, &hNativeOwner);
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (RT_UNLIKELY(hNativeOwner != hNativeSelf))
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync AssertMsgFailed(("Not owner of mutex %p!! hNativeSelf=%RTntrd Owner=%RTntrd cRecursions=%d\n",
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync pThis, hNativeSelf, hNativeOwner, pThis->cRecursions));
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync return VERR_NOT_OWNER;
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync }
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync if (pThis->cRecursions > 1)
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync {
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync#ifdef RTSEMMUTEX_STRICT
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync int rc9 = RTLockValidatorRecExclUnwind(&pThis->ValidatorRec);
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync if (RT_FAILURE(rc9))
d2c6b2e8826a5ef34170fef0c72c3fc7c5c1b46avboxsync return rc9;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync#endif
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync ASMAtomicDecU32(&pThis->cRecursions);
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync return VINF_SUCCESS;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync }
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync /*
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync * Unlock mutex semaphore.
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync */
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync#ifdef RTSEMMUTEX_STRICT
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync int rc9 = RTLockValidatorRecExclReleaseOwner(&pThis->ValidatorRec, false);
1759f65b60e18f669f6d569aebd4fb7217ab414fvboxsync if (RT_FAILURE(rc9))
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync return rc9;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync#endif
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync ASMAtomicWriteU32(&pThis->cRecursions, 0);
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync ASMAtomicWriteHandle(&pThis->hNativeOwner, NIL_RTNATIVETHREAD);
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync if (ReleaseMutex(pThis->hMtx))
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync return VINF_SUCCESS;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
8c97c335e49609421316d92d2e0aff3e7f8eed04vboxsync int rc = RTErrConvertFromWin32(GetLastError());
6ca8a1595bddf29de7894958ae74c255eb2693bevboxsync AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError()));
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync return rc;
d2c6b2e8826a5ef34170fef0c72c3fc7c5c1b46avboxsync}
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsyncRTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex)
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync{
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync /*
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync * Validate.
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync */
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync RTSEMMUTEXINTERNAL *pThis = hMutex;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync AssertPtrReturn(pThis, false);
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, false);
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync RTNATIVETHREAD hNativeOwner;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync ASMAtomicReadHandle(&pThis->hNativeOwner, &hNativeOwner);
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync return hNativeOwner != NIL_RTNATIVETHREAD;
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync}
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync
90eb38579e280c6a0e466177b2a9632ab9eb8c44vboxsync