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