xref: /trunk/main/sal/osl/unx/mutex.c (revision 02cabb04)
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