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