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