VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp@ 25491

Last change on this file since 25491 was 25491, checked in by vboxsync, 15 years ago

IPRT,PDMCritSect: Fixing critsect regression; contains under construction rw deadlock detection code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1/* $Id: semmutex-win.cpp 25491 2009-12-18 15:20:48Z vboxsync $ */
2/** @file
3 * IPRT - Mutex Semaphores, Windows.
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define LOG_GROUP RTLOGGROUP_SEMAPHORE
36#include <Windows.h>
37
38#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>
46#include <iprt/thread.h>
47#include "internal/magics.h"
48#include "internal/strict.h"
49
50
51/*******************************************************************************
52* Defined Constants And Macros *
53*******************************************************************************/
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};
66
67
68/* Undefine debug mappings. */
69#undef RTSemMutexRequest
70#undef RTSemMutexRequestNoResume
71
72
73RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
74{
75 int rc;
76
77 /*
78 * Create the semaphore.
79 */
80 HANDLE hMtx = CreateMutex(NULL, FALSE, NULL);
81 if (hMtx)
82 {
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 RTLockValidatorRecInit(&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)
110 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()));
126 }
127
128#ifdef RTSEMMUTEX_STRICT
129 RTLockValidatorRecDelete(&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 pSrcPos The source position of the caller.
143 */
144DECL_FORCE_INLINE(int) rtSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies, PCRTLOCKVALIDATORSRCPOS pSrcPos)
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, pSrcPos);
156#else
157 RTTHREAD hThreadSelf = RTThreadSelf();
158#endif
159
160 /*
161 * Lock mutex semaphore.
162 */
163 if (cMillies > 0)
164 {
165#ifdef RTSEMMUTEX_STRICT
166 int rc9 = RTLockValidatorCheckBlocking(&pThis->ValidatorRec, hThreadSelf,
167 RTTHREADSTATE_MUTEX, true, pSrcPos);
168 if (RT_FAILURE(rc9))
169 return rc9;
170#endif
171 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
172 }
173 int rc = WaitForSingleObjectEx(pThis->hMtx,
174 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
175 TRUE /*bAlertable*/);
176 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
177 switch (rc)
178 {
179 case WAIT_OBJECT_0:
180#ifdef RTSEMMUTEX_STRICT
181 RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, pSrcPos);
182#endif
183 return VINF_SUCCESS;
184
185 case WAIT_TIMEOUT: return VERR_TIMEOUT;
186 case WAIT_IO_COMPLETION: return VERR_INTERRUPTED;
187 case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED;
188 default:
189 {
190 AssertMsgFailed(("Wait on MutexSem %p failed, rc=%d lasterr=%d\n", MutexSem, rc, GetLastError()));
191 int rc2 = RTErrConvertFromWin32(GetLastError());
192 if (rc2 != 0)
193 return rc2;
194
195 AssertMsgFailed(("WaitForSingleObject(event) -> rc=%d while converted lasterr=%d\n", rc, rc2));
196 return VERR_INTERNAL_ERROR;
197 }
198 }
199}
200
201
202RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
203{
204#ifndef RTSEMMUTEX_STRICT
205 return rtSemMutexRequestNoResume(MutexSem, cMillies, NULL);
206#else
207 RTLOCKVALIDATORSRCPOS SrcPos = RTLOCKVALIDATORSRCPOS_INIT_NORMAL_API();
208 return rtSemMutexRequestNoResume(MutexSem, cMillies, &SrcPos);
209#endif
210}
211
212
213RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
214{
215 RTLOCKVALIDATORSRCPOS SrcPos = RTLOCKVALIDATORSRCPOS_INIT_DEBUG_API();
216 return rtSemMutexRequestNoResume(MutexSem, cMillies, &SrcPos);
217}
218
219
220RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
221{
222 /*
223 * Validate.
224 */
225 RTSEMMUTEXINTERNAL *pThis = MutexSem;
226 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
227 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
228
229 /*
230 * Unlock mutex semaphore.
231 */
232#ifdef RTSEMMUTEX_STRICT
233 if ( pThis->ValidatorRec.hThread != NIL_RTTHREAD
234 && pThis->ValidatorRec.hThread == RTThreadSelf())
235 RTLockValidatorUnsetOwner(&pThis->ValidatorRec);
236 else
237 AssertMsgFailed(("%p hThread=%RTthrd\n", pThis, pThis->ValidatorRec.hThread));
238#endif
239 if (ReleaseMutex(pThis->hMtx))
240 return VINF_SUCCESS;
241 int rc = RTErrConvertFromWin32(GetLastError());
242 AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError()));
243 return rc;
244}
245
Note: See TracBrowser for help on using the repository browser.

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