xref: /trunk/main/sal/osl/w32/mutex.c (revision 647f063d)
1*647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647f063dSAndrew Rist  * distributed with this work for additional information
6*647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9*647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647f063dSAndrew Rist  *
11*647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647f063dSAndrew Rist  *
13*647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647f063dSAndrew Rist  * software distributed under the License is distributed on an
15*647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647f063dSAndrew Rist  * specific language governing permissions and limitations
18*647f063dSAndrew Rist  * under the License.
19*647f063dSAndrew Rist  *
20*647f063dSAndrew Rist  *************************************************************/
21*647f063dSAndrew Rist 
22*647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "system.h"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <osl/mutex.h>
27cdf0e10cSrcweir #include <osl/diagnose.h>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir /*
30cdf0e10cSrcweir 	Implementation notes:
31cdf0e10cSrcweir 	The void* hidden by oslMutex points to a WIN32
32cdf0e10cSrcweir 	CRITICAL_SECTION structure.
33cdf0e10cSrcweir */
34cdf0e10cSrcweir 
35cdf0e10cSrcweir typedef struct _oslMutexImpl {
36cdf0e10cSrcweir 	CRITICAL_SECTION	m_Mutex;
37cdf0e10cSrcweir 	int 				m_Locks;
38cdf0e10cSrcweir 	DWORD				m_Owner;
39cdf0e10cSrcweir 	DWORD				m_Requests;
40cdf0e10cSrcweir } oslMutexImpl;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir static BOOL (WINAPI *lpfTryEnterCriticalSection)(LPCRITICAL_SECTION)
43cdf0e10cSrcweir 	= (BOOL (WINAPI *)(LPCRITICAL_SECTION))0xFFFFFFFF;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir static CRITICAL_SECTION MutexLock;
46cdf0e10cSrcweir 
47cdf0e10cSrcweir /*****************************************************************************/
48cdf0e10cSrcweir /* osl_createMutex */
49cdf0e10cSrcweir /*****************************************************************************/
osl_createMutex(void)50cdf0e10cSrcweir oslMutex SAL_CALL osl_createMutex(void)
51cdf0e10cSrcweir {
52cdf0e10cSrcweir 	oslMutexImpl *pMutexImpl;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 	/* Window 95 does not support "TryEnterCriticalSection" */
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 	if (lpfTryEnterCriticalSection ==
57cdf0e10cSrcweir 				(BOOL (WINAPI *)(LPCRITICAL_SECTION))0xFFFFFFFF)
58cdf0e10cSrcweir 	{
59cdf0e10cSrcweir 		OSVERSIONINFO VersionInformation =
60cdf0e10cSrcweir 
61cdf0e10cSrcweir 		{
62cdf0e10cSrcweir 			sizeof(OSVERSIONINFO),
63cdf0e10cSrcweir 			0,
64cdf0e10cSrcweir 	    	0,
65cdf0e10cSrcweir 	    	0,
66cdf0e10cSrcweir 	    	0,
67cdf0e10cSrcweir 	    	"",
68cdf0e10cSrcweir 		};
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 		/* ts: Window 98 does not support "TryEnterCriticalSection" but export the symbol !!!
71cdf0e10cSrcweir 		   calls to that symbol always returns FALSE */
72cdf0e10cSrcweir 		if (
73cdf0e10cSrcweir 			GetVersionEx(&VersionInformation) &&
74cdf0e10cSrcweir 			(VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT)
75cdf0e10cSrcweir 		   )
76cdf0e10cSrcweir 		{
77cdf0e10cSrcweir 			lpfTryEnterCriticalSection = (BOOL (WINAPI *)(LPCRITICAL_SECTION))
78cdf0e10cSrcweir 					GetProcAddress(GetModuleHandle("KERNEL32"),
79cdf0e10cSrcweir 								   "TryEnterCriticalSection");
80cdf0e10cSrcweir 		}
81cdf0e10cSrcweir 		else
82cdf0e10cSrcweir 		{
83cdf0e10cSrcweir 			lpfTryEnterCriticalSection = (BOOL (WINAPI *)(LPCRITICAL_SECTION))NULL;
84cdf0e10cSrcweir 		}
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 		InitializeCriticalSection(&MutexLock);
88cdf0e10cSrcweir 	}
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 	pMutexImpl= calloc(sizeof(oslMutexImpl), 1);
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 	OSL_ASSERT(pMutexImpl); /* alloc successful? */
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 	InitializeCriticalSection(&pMutexImpl->m_Mutex);
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	return (oslMutex)pMutexImpl;
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir /*****************************************************************************/
100cdf0e10cSrcweir /* osl_destroyMutex */
101cdf0e10cSrcweir /*****************************************************************************/
osl_destroyMutex(oslMutex Mutex)102cdf0e10cSrcweir void SAL_CALL osl_destroyMutex(oslMutex Mutex)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 	if (pMutexImpl)
107cdf0e10cSrcweir 	{
108cdf0e10cSrcweir 		DeleteCriticalSection(&pMutexImpl->m_Mutex);
109cdf0e10cSrcweir 		free(pMutexImpl);
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir /*****************************************************************************/
114cdf0e10cSrcweir /* osl_acquireMutex */
115cdf0e10cSrcweir /*****************************************************************************/
osl_acquireMutex(oslMutex Mutex)116cdf0e10cSrcweir sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex)
117cdf0e10cSrcweir {
118cdf0e10cSrcweir 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 	OSL_ASSERT(Mutex);
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 	if (lpfTryEnterCriticalSection == NULL)
123cdf0e10cSrcweir 	{
124cdf0e10cSrcweir 		EnterCriticalSection(&MutexLock);
125cdf0e10cSrcweir 		pMutexImpl->m_Requests++;
126cdf0e10cSrcweir 		LeaveCriticalSection(&MutexLock);
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 		EnterCriticalSection(&pMutexImpl->m_Mutex);
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 		EnterCriticalSection(&MutexLock);
131cdf0e10cSrcweir 		pMutexImpl->m_Requests--;
132cdf0e10cSrcweir 		if (pMutexImpl->m_Locks++ == 0)
133cdf0e10cSrcweir 			pMutexImpl->m_Owner = GetCurrentThreadId();
134cdf0e10cSrcweir 		LeaveCriticalSection(&MutexLock);
135cdf0e10cSrcweir 	}
136cdf0e10cSrcweir 	else
137cdf0e10cSrcweir 		EnterCriticalSection(&pMutexImpl->m_Mutex);
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	return sal_True;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir /*****************************************************************************/
143cdf0e10cSrcweir /* osl_tryToAcquireMutex */
144cdf0e10cSrcweir /*****************************************************************************/
osl_tryToAcquireMutex(oslMutex Mutex)145cdf0e10cSrcweir sal_Bool SAL_CALL osl_tryToAcquireMutex(oslMutex Mutex)
146cdf0e10cSrcweir {
147cdf0e10cSrcweir 	sal_Bool 	 ret = sal_False;
148cdf0e10cSrcweir 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 	OSL_ASSERT(Mutex);
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	if (lpfTryEnterCriticalSection != NULL)
153cdf0e10cSrcweir 		return (sal_Bool)(lpfTryEnterCriticalSection(&pMutexImpl->m_Mutex) != FALSE);
154cdf0e10cSrcweir 	else
155cdf0e10cSrcweir 	{
156cdf0e10cSrcweir 		EnterCriticalSection(&MutexLock);
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 		if ( ((pMutexImpl->m_Requests == 0) && (pMutexImpl->m_Locks == 0)) ||
159cdf0e10cSrcweir 			 (pMutexImpl->m_Owner == GetCurrentThreadId()) )
160cdf0e10cSrcweir 			ret = osl_acquireMutex(Mutex);
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 		LeaveCriticalSection(&MutexLock);
163cdf0e10cSrcweir 	}
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 	return ret;
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir /*****************************************************************************/
169cdf0e10cSrcweir /* osl_releaseMutex */
170cdf0e10cSrcweir /*****************************************************************************/
osl_releaseMutex(oslMutex Mutex)171cdf0e10cSrcweir sal_Bool SAL_CALL osl_releaseMutex(oslMutex Mutex)
172cdf0e10cSrcweir {
173cdf0e10cSrcweir 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 	OSL_ASSERT(Mutex);
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 	if (lpfTryEnterCriticalSection == NULL)
178cdf0e10cSrcweir 	{
179cdf0e10cSrcweir 		EnterCriticalSection(&MutexLock);
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 		if (--(pMutexImpl->m_Locks) == 0)
182cdf0e10cSrcweir 			pMutexImpl->m_Owner = 0;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 		LeaveCriticalSection(&MutexLock);
185cdf0e10cSrcweir 	}
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 	LeaveCriticalSection(&pMutexImpl->m_Mutex);
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 	return sal_True;
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
192cdf0e10cSrcweir /*****************************************************************************/
193cdf0e10cSrcweir /* osl_getGlobalMutex */
194cdf0e10cSrcweir /*****************************************************************************/
195cdf0e10cSrcweir 
196cdf0e10cSrcweir /* initialized in dllentry.c */
197cdf0e10cSrcweir oslMutex g_Mutex;
198cdf0e10cSrcweir 
osl_getGlobalMutex(void)199cdf0e10cSrcweir oslMutex * SAL_CALL osl_getGlobalMutex(void)
200cdf0e10cSrcweir {
201cdf0e10cSrcweir 	return &g_Mutex;
202cdf0e10cSrcweir }
203