1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "system.h" 29 30 #include <osl/mutex.h> 31 #include <osl/diagnose.h> 32 33 /* 34 Implementation notes: 35 The void* hidden by oslMutex points to a WIN32 36 CRITICAL_SECTION structure. 37 */ 38 39 typedef struct _oslMutexImpl { 40 CRITICAL_SECTION m_Mutex; 41 int m_Locks; 42 DWORD m_Owner; 43 DWORD m_Requests; 44 } oslMutexImpl; 45 46 static BOOL (WINAPI *lpfTryEnterCriticalSection)(LPCRITICAL_SECTION) 47 = (BOOL (WINAPI *)(LPCRITICAL_SECTION))0xFFFFFFFF; 48 49 static CRITICAL_SECTION MutexLock; 50 51 /*****************************************************************************/ 52 /* osl_createMutex */ 53 /*****************************************************************************/ 54 oslMutex SAL_CALL osl_createMutex(void) 55 { 56 oslMutexImpl *pMutexImpl; 57 58 /* Window 95 does not support "TryEnterCriticalSection" */ 59 60 if (lpfTryEnterCriticalSection == 61 (BOOL (WINAPI *)(LPCRITICAL_SECTION))0xFFFFFFFF) 62 { 63 OSVERSIONINFO VersionInformation = 64 65 { 66 sizeof(OSVERSIONINFO), 67 0, 68 0, 69 0, 70 0, 71 "", 72 }; 73 74 /* ts: Window 98 does not support "TryEnterCriticalSection" but export the symbol !!! 75 calls to that symbol always returns FALSE */ 76 if ( 77 GetVersionEx(&VersionInformation) && 78 (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT) 79 ) 80 { 81 lpfTryEnterCriticalSection = (BOOL (WINAPI *)(LPCRITICAL_SECTION)) 82 GetProcAddress(GetModuleHandle("KERNEL32"), 83 "TryEnterCriticalSection"); 84 } 85 else 86 { 87 lpfTryEnterCriticalSection = (BOOL (WINAPI *)(LPCRITICAL_SECTION))NULL; 88 } 89 90 91 InitializeCriticalSection(&MutexLock); 92 } 93 94 pMutexImpl= calloc(sizeof(oslMutexImpl), 1); 95 96 OSL_ASSERT(pMutexImpl); /* alloc successful? */ 97 98 InitializeCriticalSection(&pMutexImpl->m_Mutex); 99 100 return (oslMutex)pMutexImpl; 101 } 102 103 /*****************************************************************************/ 104 /* osl_destroyMutex */ 105 /*****************************************************************************/ 106 void SAL_CALL osl_destroyMutex(oslMutex Mutex) 107 { 108 oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex; 109 110 if (pMutexImpl) 111 { 112 DeleteCriticalSection(&pMutexImpl->m_Mutex); 113 free(pMutexImpl); 114 } 115 } 116 117 /*****************************************************************************/ 118 /* osl_acquireMutex */ 119 /*****************************************************************************/ 120 sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex) 121 { 122 oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex; 123 124 OSL_ASSERT(Mutex); 125 126 if (lpfTryEnterCriticalSection == NULL) 127 { 128 EnterCriticalSection(&MutexLock); 129 pMutexImpl->m_Requests++; 130 LeaveCriticalSection(&MutexLock); 131 132 EnterCriticalSection(&pMutexImpl->m_Mutex); 133 134 EnterCriticalSection(&MutexLock); 135 pMutexImpl->m_Requests--; 136 if (pMutexImpl->m_Locks++ == 0) 137 pMutexImpl->m_Owner = GetCurrentThreadId(); 138 LeaveCriticalSection(&MutexLock); 139 } 140 else 141 EnterCriticalSection(&pMutexImpl->m_Mutex); 142 143 return sal_True; 144 } 145 146 /*****************************************************************************/ 147 /* osl_tryToAcquireMutex */ 148 /*****************************************************************************/ 149 sal_Bool SAL_CALL osl_tryToAcquireMutex(oslMutex Mutex) 150 { 151 sal_Bool ret = sal_False; 152 oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex; 153 154 OSL_ASSERT(Mutex); 155 156 if (lpfTryEnterCriticalSection != NULL) 157 return (sal_Bool)(lpfTryEnterCriticalSection(&pMutexImpl->m_Mutex) != FALSE); 158 else 159 { 160 EnterCriticalSection(&MutexLock); 161 162 if ( ((pMutexImpl->m_Requests == 0) && (pMutexImpl->m_Locks == 0)) || 163 (pMutexImpl->m_Owner == GetCurrentThreadId()) ) 164 ret = osl_acquireMutex(Mutex); 165 166 LeaveCriticalSection(&MutexLock); 167 } 168 169 return ret; 170 } 171 172 /*****************************************************************************/ 173 /* osl_releaseMutex */ 174 /*****************************************************************************/ 175 sal_Bool SAL_CALL osl_releaseMutex(oslMutex Mutex) 176 { 177 oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex; 178 179 OSL_ASSERT(Mutex); 180 181 if (lpfTryEnterCriticalSection == NULL) 182 { 183 EnterCriticalSection(&MutexLock); 184 185 if (--(pMutexImpl->m_Locks) == 0) 186 pMutexImpl->m_Owner = 0; 187 188 LeaveCriticalSection(&MutexLock); 189 } 190 191 LeaveCriticalSection(&pMutexImpl->m_Mutex); 192 193 return sal_True; 194 } 195 196 /*****************************************************************************/ 197 /* osl_getGlobalMutex */ 198 /*****************************************************************************/ 199 200 /* initialized in dllentry.c */ 201 oslMutex g_Mutex; 202 203 oslMutex * SAL_CALL osl_getGlobalMutex(void) 204 { 205 return &g_Mutex; 206 } 207