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 /*****************************************************************************/
osl_createMutex()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 == 0 )
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 = 0;
79 }
80
81 pthread_mutexattr_destroy(&aMutexAttr);
82
83 return (oslMutex) pMutex;
84 }
85
86 /*****************************************************************************/
87 /* osl_destroyMutex */
88 /*****************************************************************************/
osl_destroyMutex(oslMutex Mutex)89 void SAL_CALL osl_destroyMutex(oslMutex Mutex)
90 {
91 oslMutexImpl* pMutex = (oslMutexImpl*) Mutex;
92
93 OSL_ASSERT(pMutex);
94
95 if ( pMutex != 0 )
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 /*****************************************************************************/
osl_acquireMutex(oslMutex Mutex)115 sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex)
116 {
117 oslMutexImpl* pMutex = (oslMutexImpl*) Mutex;
118
119 OSL_ASSERT(pMutex);
120
121 if ( pMutex != 0 )
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 /*****************************************************************************/
osl_tryToAcquireMutex(oslMutex Mutex)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 /*****************************************************************************/
osl_releaseMutex(oslMutex Mutex)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
globalMutexInitImpl(void)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
osl_getGlobalMutex()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