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