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