VirtualBox

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

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

IPRT,PDMCritSect: More lock validation.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/* $Id: semmutex-win.cpp 25467 2009-12-17 15:16:55Z 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 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)
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 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
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, uId, RT_SRC_POS_ARGS);
168 if (RT_FAILURE(rc9))
169 return rc9;
170#else
171 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
172#endif
173 }
174 int rc = WaitForSingleObjectEx(pThis->hMtx,
175 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
176 TRUE /*bAlertable*/);
177 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
178 switch (rc)
179 {
180 case WAIT_OBJECT_0:
181#ifdef RTSEMMUTEX_STRICT
182 RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS);
183#endif
184 return VINF_SUCCESS;
185
186 case WAIT_TIMEOUT: return VERR_TIMEOUT;
187 case WAIT_IO_COMPLETION: return VERR_INTERRUPTED;
188 case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED;
189 default:
190 {
191 AssertMsgFailed(("Wait on MutexSem %p failed, rc=%d lasterr=%d\n", MutexSem, rc, GetLastError()));
192 int rc2 = RTErrConvertFromWin32(GetLastError());
193 if (rc2 != 0)
194 return rc2;
195
196 AssertMsgFailed(("WaitForSingleObject(event) -> rc=%d while converted lasterr=%d\n", rc, rc2));
197 return VERR_INTERNAL_ERROR;
198 }
199 }
200}
201
202
203RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
204{
205#ifndef RTSEMMUTEX_STRICT
206 return rtSemMutexRequestNoResume(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
207#else
208 return RTSemMutexRequestNoResumeDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
209#endif
210}
211
212
213RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
214{
215#ifdef RTSEMMUTEX_STRICT
216 return rtSemMutexRequestNoResume(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
217#else
218 return RTSemMutexRequestNoResume(MutexSem, cMillies);
219#endif
220}
221
222
223RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
224{
225 /*
226 * Validate.
227 */
228 RTSEMMUTEXINTERNAL *pThis = MutexSem;
229 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
230 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
231
232 /*
233 * Unlock mutex semaphore.
234 */
235#ifdef RTSEMMUTEX_STRICT
236 if ( pThis->ValidatorRec.hThread != NIL_RTTHREAD
237 && pThis->ValidatorRec.hThread == RTThreadSelf())
238 RTLockValidatorUnsetOwner(&pThis->ValidatorRec);
239 else
240 AssertMsgFailed(("%p hThread=%RTthrd\n", pThis, pThis->ValidatorRec.hThread));
241#endif
242 if (ReleaseMutex(pThis->hMtx))
243 return VINF_SUCCESS;
244 int rc = RTErrConvertFromWin32(GetLastError());
245 AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError()));
246 return rc;
247}
248
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