xref: /aoo41x/main/sal/osl/os2/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 <sys/fmutex.h>
29 
30 #include "system.h"
31 
32 #include <osl/mutex.h>
33 #include <osl/diagnose.h>
34 
35 /*
36     Implementation notes:
37     The void* hidden by oslMutex points to an OS/2 mutex semaphore.
38 */
39 typedef struct _oslMutexImpl {
40 	HMTX				m_Mutex;
41 	int 				m_Locks;
42 	ULONG				m_Owner;
43 	ULONG				m_Requests;
44 } oslMutexImpl;
45 
46 // static mutex to control access to private members of oslMutexImpl
47 static HMTX MutexLock = 0;
48 
49 /*****************************************************************************/
50 /* osl_createMutex */
51 /*****************************************************************************/
52 oslMutex SAL_CALL osl_createMutex()
53 {
54 	oslMutexImpl *pMutexImpl;
55     HMTX hMutex;
56     APIRET rc;
57 
58 	pMutexImpl= (oslMutexImpl*)calloc(sizeof(oslMutexImpl), 1);
59 	OSL_ASSERT(pMutexImpl); /* alloc successful? */
60 
61     /* create semaphore */
62     rc = DosCreateMutexSem( NULL, &pMutexImpl->m_Mutex, 0, FALSE );
63     if( rc != 0 )
64 	{
65 		free(pMutexImpl);
66         return NULL;
67 	}
68 
69 	// create static mutex for private members
70 	if (MutexLock == 0)
71 		DosCreateMutexSem( NULL, &MutexLock, 0, FALSE );
72 
73 	return (oslMutex)pMutexImpl;
74 }
75 
76 /*****************************************************************************/
77 /* osl_destroyMutex */
78 /*****************************************************************************/
79 void SAL_CALL osl_destroyMutex(oslMutex Mutex)
80 {
81 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
82 	if (pMutexImpl)
83 	{
84 		DosCloseMutexSem( pMutexImpl->m_Mutex);
85 		free(pMutexImpl);
86 	}
87 }
88 
89 /*****************************************************************************/
90 /* osl_acquireMutex */
91 /*****************************************************************************/
92 sal_Bool SAL_CALL osl_acquireMutex(oslMutex Mutex)
93 {
94 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
95     APIRET rc = 0;
96     OSL_ASSERT(Mutex);
97 
98 	DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
99 	pMutexImpl->m_Requests++;
100 	DosReleaseMutexSem( MutexLock);
101 
102 	rc = DosRequestMutexSem( pMutexImpl->m_Mutex, SEM_INDEFINITE_WAIT );
103 
104 	DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
105 	pMutexImpl->m_Requests--;
106 	if (pMutexImpl->m_Locks++ == 0)
107 		pMutexImpl->m_Owner = _gettid();
108 	DosReleaseMutexSem( MutexLock);
109 
110     return( rc == 0 );
111 }
112 
113 /*****************************************************************************/
114 /* osl_tryToAcquireMutex */
115 /*****************************************************************************/
116 sal_Bool SAL_CALL osl_tryToAcquireMutex(oslMutex Mutex)
117 {
118 	sal_Bool 	 ret = sal_False;
119 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
120     OSL_ASSERT(Mutex);
121 
122 	DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
123 
124 	if ( ((pMutexImpl->m_Requests == 0) && (pMutexImpl->m_Locks == 0)) ||
125 		 (pMutexImpl->m_Owner == _gettid()) )
126 		ret = osl_acquireMutex(Mutex);
127 
128 	DosReleaseMutexSem( MutexLock);
129 
130     return ret;
131 }
132 
133 /*****************************************************************************/
134 /* osl_releaseMutex */
135 /*****************************************************************************/
136 sal_Bool SAL_CALL osl_releaseMutex(oslMutex Mutex)
137 {
138 	oslMutexImpl *pMutexImpl = (oslMutexImpl *)Mutex;
139     APIRET rc;
140     OSL_ASSERT(Mutex);
141 
142 	DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
143 
144 	if (--(pMutexImpl->m_Locks) == 0)
145 		pMutexImpl->m_Owner = 0;
146 
147 	DosReleaseMutexSem( MutexLock);
148 
149     rc = DosReleaseMutexSem( pMutexImpl->m_Mutex);
150 
151     return sal_True;
152 }
153 
154 
155 
156 /*****************************************************************************/
157 /* osl_getGlobalMutex */
158 /*****************************************************************************/
159 
160 oslMutex g_Mutex = NULL;
161 
162 oslMutex * SAL_CALL osl_getGlobalMutex(void)
163 {
164 	if (g_Mutex == NULL)
165 		g_Mutex = osl_createMutex();
166 	return &g_Mutex;
167 }
168