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