xref: /aoo41x/main/sal/osl/unx/mutex.c (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "system.h"
29 
30 #include <osl/mutex.h>
31 #include <osl/diagnose.h>
32 
33 #include <pthread.h>
34 #include <stdlib.h>
35 
36 #if defined LINUX /* bad hack */
37 int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
38 #define pthread_mutexattr_settype pthread_mutexattr_setkind_np
39 #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
40 #endif
41 
42 /*
43 	Implementation notes:
44 	oslMutex hides a pointer to the oslMutexImpl structure, which
45 	ist needed to manage recursive locks on a mutex.
46 
47 */
48 
49 typedef struct _oslMutexImpl
50 {
51 	pthread_mutex_t	mutex;
52 } oslMutexImpl;
53 
54 
55 /*****************************************************************************/
56 /* osl_createMutex */
57 /*****************************************************************************/
58 oslMutex SAL_CALL osl_createMutex()
59 {
60 	oslMutexImpl* pMutex = (oslMutexImpl*) malloc(sizeof(oslMutexImpl));
61     pthread_mutexattr_t aMutexAttr;
62     int nRet=0;
63 
64 	OSL_ASSERT(pMutex);
65 
66 	if ( pMutex == 0 )
67 	{
68 		return 0;
69 	}
70 
71     pthread_mutexattr_init(&aMutexAttr);
72 
73     nRet = pthread_mutexattr_settype(&aMutexAttr, PTHREAD_MUTEX_RECURSIVE);
74 
75     nRet = pthread_mutex_init(&(pMutex->mutex), &aMutexAttr);
76 	if ( nRet != 0 )
77 	{
78 	    OSL_TRACE("osl_createMutex : mutex init failed. Errno: %d; %s\n",
79                   nRet, strerror(nRet));
80 
81 	    free(pMutex);
82 		pMutex = 0;
83 	}
84 
85     pthread_mutexattr_destroy(&aMutexAttr);
86 
87 	return (oslMutex) pMutex;
88 }
89 
90 /*****************************************************************************/
91 /* osl_destroyMutex */
92 /*****************************************************************************/
93 void SAL_CALL osl_destroyMutex(oslMutex Mutex)
94 {
95 	oslMutexImpl* pMutex = (oslMutexImpl*) Mutex;
96 
97     OSL_ASSERT(pMutex);
98 
99 	if ( pMutex != 0 )
100 	{
101         int nRet=0;
102 
103 	    nRet = pthread_mutex_destroy(&(pMutex->mutex));
104         if ( nRet != 0 )
105         {
106             OSL_TRACE("osl_destroyMutex : mutex destroy failed. Errno: %d; %s\n",
107                       nRet, strerror(nRet));
108         }
109 
110 		free(pMutex);
111 	}
112 
113     return;
114 }
115 
116 /*****************************************************************************/
117 /* osl_acquireMutex */
118 /*****************************************************************************/
119 sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex)
120 {
121 	oslMutexImpl* pMutex = (oslMutexImpl*) Mutex;
122 
123     OSL_ASSERT(pMutex);
124 
125 	if ( pMutex != 0 )
126 	{
127         int nRet=0;
128 
129         nRet = pthread_mutex_lock(&(pMutex->mutex));
130         if ( nRet != 0 )
131         {
132             OSL_TRACE("osl_acquireMutex : mutex lock failed. Errno: %d; %s\n",
133                       nRet, strerror(nRet));
134 			return sal_False;
135         }
136 		return sal_True;
137 	}
138 
139     /* not initialized */
140     return sal_False;
141 }
142 
143 /*****************************************************************************/
144 /* osl_tryToAcquireMutex */
145 /*****************************************************************************/
146 sal_Bool SAL_CALL osl_tryToAcquireMutex(oslMutex Mutex)
147 {
148 	oslMutexImpl* pMutex = (oslMutexImpl*) Mutex;
149 
150     OSL_ASSERT(pMutex);
151 
152 	if ( pMutex )
153 	{
154 		int nRet = 0;
155         nRet = pthread_mutex_trylock(&(pMutex->mutex));
156         if ( nRet != 0  )
157             return sal_False;
158 
159 		return sal_True;
160 	}
161 
162     /* not initialized */
163     return sal_False;
164 }
165 
166 /*****************************************************************************/
167 /* osl_releaseMutex */
168 /*****************************************************************************/
169 sal_Bool SAL_CALL osl_releaseMutex(oslMutex Mutex)
170 {
171 	oslMutexImpl* pMutex = (oslMutexImpl*) Mutex;
172 
173     OSL_ASSERT(pMutex);
174 
175 	if ( pMutex )
176 	{
177         int nRet=0;
178         nRet = pthread_mutex_unlock(&(pMutex->mutex));
179         if ( nRet != 0 )
180         {
181             OSL_TRACE("osl_releaseMutex : mutex unlock failed. Errno: %d; %s\n",
182                       nRet, strerror(nRet));
183 			return sal_False;
184         }
185 
186         return sal_True;
187 	}
188 
189     /* not initialized */
190     return sal_False;
191 }
192 
193 /*****************************************************************************/
194 /* osl_getGlobalMutex */
195 /*****************************************************************************/
196 
197 static oslMutexImpl globalMutexImpl;
198 
199 static void globalMutexInitImpl(void) {
200     pthread_mutexattr_t attr;
201     if (pthread_mutexattr_init(&attr) != 0 ||
202         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) ||
203         pthread_mutex_init(&globalMutexImpl.mutex, &attr) != 0 ||
204         pthread_mutexattr_destroy(&attr) != 0)
205     {
206         abort();
207     }
208 }
209 
210 oslMutex * SAL_CALL osl_getGlobalMutex()
211 {
212 	/* necessary to get a "oslMutex *" */
213 	static oslMutex globalMutex = (oslMutex) &globalMutexImpl;
214 
215     static pthread_once_t once = PTHREAD_ONCE_INIT;
216     if (pthread_once(&once, &globalMutexInitImpl) != 0) {
217         abort();
218     }
219 
220 	return &globalMutex;
221 }
222