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