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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 158 oslMutex * SAL_CALL osl_getGlobalMutex(void) 159 { 160 if (g_Mutex == NULL) 161 g_Mutex = osl_createMutex(); 162 return &g_Mutex; 163 } 164