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