xref: /AOO41X/main/sal/osl/unx/mutex.c (revision d5b37d1cdb91c4ac6e73fa6110cd737d9cf84eda)
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 == 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 /*****************************************************************************/
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 != 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 /*****************************************************************************/
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 != 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 /*****************************************************************************/
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