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