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 #include <pthread.h> 34 #include <stdlib.h> 35 36 #if defined LINUX /* bad hack */ 37 int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int); 38 #define pthread_mutexattr_settype pthread_mutexattr_setkind_np 39 #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP 40 #endif 41 42 /* 43 Implementation notes: 44 oslMutex hides a pointer to the oslMutexImpl structure, which 45 ist needed to manage recursive locks on a mutex. 46 47 */ 48 49 typedef struct _oslMutexImpl 50 { 51 pthread_mutex_t mutex; 52 } oslMutexImpl; 53 54 55 /*****************************************************************************/ 56 /* osl_createMutex */ 57 /*****************************************************************************/ 58 oslMutex SAL_CALL osl_createMutex() 59 { 60 oslMutexImpl* pMutex = (oslMutexImpl*) malloc(sizeof(oslMutexImpl)); 61 pthread_mutexattr_t aMutexAttr; 62 int nRet=0; 63 64 OSL_ASSERT(pMutex); 65 66 if ( pMutex == 0 ) 67 { 68 return 0; 69 } 70 71 pthread_mutexattr_init(&aMutexAttr); 72 73 nRet = pthread_mutexattr_settype(&aMutexAttr, PTHREAD_MUTEX_RECURSIVE); 74 75 nRet = pthread_mutex_init(&(pMutex->mutex), &aMutexAttr); 76 if ( nRet != 0 ) 77 { 78 OSL_TRACE("osl_createMutex : mutex init failed. Errno: %d; %s\n", 79 nRet, strerror(nRet)); 80 81 free(pMutex); 82 pMutex = 0; 83 } 84 85 pthread_mutexattr_destroy(&aMutexAttr); 86 87 return (oslMutex) pMutex; 88 } 89 90 /*****************************************************************************/ 91 /* osl_destroyMutex */ 92 /*****************************************************************************/ 93 void SAL_CALL osl_destroyMutex(oslMutex Mutex) 94 { 95 oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; 96 97 OSL_ASSERT(pMutex); 98 99 if ( pMutex != 0 ) 100 { 101 int nRet=0; 102 103 nRet = pthread_mutex_destroy(&(pMutex->mutex)); 104 if ( nRet != 0 ) 105 { 106 OSL_TRACE("osl_destroyMutex : mutex destroy failed. Errno: %d; %s\n", 107 nRet, strerror(nRet)); 108 } 109 110 free(pMutex); 111 } 112 113 return; 114 } 115 116 /*****************************************************************************/ 117 /* osl_acquireMutex */ 118 /*****************************************************************************/ 119 sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex) 120 { 121 oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; 122 123 OSL_ASSERT(pMutex); 124 125 if ( pMutex != 0 ) 126 { 127 int nRet=0; 128 129 nRet = pthread_mutex_lock(&(pMutex->mutex)); 130 if ( nRet != 0 ) 131 { 132 OSL_TRACE("osl_acquireMutex : mutex lock failed. Errno: %d; %s\n", 133 nRet, strerror(nRet)); 134 return sal_False; 135 } 136 return sal_True; 137 } 138 139 /* not initialized */ 140 return sal_False; 141 } 142 143 /*****************************************************************************/ 144 /* osl_tryToAcquireMutex */ 145 /*****************************************************************************/ 146 sal_Bool SAL_CALL osl_tryToAcquireMutex(oslMutex Mutex) 147 { 148 oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; 149 150 OSL_ASSERT(pMutex); 151 152 if ( pMutex ) 153 { 154 int nRet = 0; 155 nRet = pthread_mutex_trylock(&(pMutex->mutex)); 156 if ( nRet != 0 ) 157 return sal_False; 158 159 return sal_True; 160 } 161 162 /* not initialized */ 163 return sal_False; 164 } 165 166 /*****************************************************************************/ 167 /* osl_releaseMutex */ 168 /*****************************************************************************/ 169 sal_Bool SAL_CALL osl_releaseMutex(oslMutex Mutex) 170 { 171 oslMutexImpl* pMutex = (oslMutexImpl*) Mutex; 172 173 OSL_ASSERT(pMutex); 174 175 if ( pMutex ) 176 { 177 int nRet=0; 178 nRet = pthread_mutex_unlock(&(pMutex->mutex)); 179 if ( nRet != 0 ) 180 { 181 OSL_TRACE("osl_releaseMutex : mutex unlock failed. Errno: %d; %s\n", 182 nRet, strerror(nRet)); 183 return sal_False; 184 } 185 186 return sal_True; 187 } 188 189 /* not initialized */ 190 return sal_False; 191 } 192 193 /*****************************************************************************/ 194 /* osl_getGlobalMutex */ 195 /*****************************************************************************/ 196 197 static oslMutexImpl globalMutexImpl; 198 199 static void globalMutexInitImpl(void) { 200 pthread_mutexattr_t attr; 201 if (pthread_mutexattr_init(&attr) != 0 || 202 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) || 203 pthread_mutex_init(&globalMutexImpl.mutex, &attr) != 0 || 204 pthread_mutexattr_destroy(&attr) != 0) 205 { 206 abort(); 207 } 208 } 209 210 oslMutex * SAL_CALL osl_getGlobalMutex() 211 { 212 /* necessary to get a "oslMutex *" */ 213 static oslMutex globalMutex = (oslMutex) &globalMutexImpl; 214 215 static pthread_once_t once = PTHREAD_ONCE_INIT; 216 if (pthread_once(&once, &globalMutexInitImpl) != 0) { 217 abort(); 218 } 219 220 return &globalMutex; 221 } 222