First public contribution.
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 // Interface : POSIX, pthread
17 // POSIX implementation of mutexes on Symbian
23 #include "mutextypes.h"
26 This function waits on the aLock semaphore.
28 int _doWait(RSemaphore* aLock, const struct timespec *abstime)
37 long lSleepTime = _microsleeptime(abstime);
45 else if(ETIMEDOUT == errno)
53 retval = aLock->Wait(lSleepTime);
54 if(retval != KErrNone)
64 This internal function destroys the mutex object.
66 void _closeMutex(pthread_mutex_t* mutex)
68 _pthread_mutex_t* pMutex = mutex->iPtr;
71 if(pMutex->iSemaphoreCreated)
73 pMutex->iSignalSemaphore.Close();
75 if(pMutex->iDataLockCreated)
77 pMutex->iDataLock.Close();
85 int _mutexCreate (pthread_mutex_t * mutex,
86 const pthread_mutexattr_t* attr)
89 if( attr->iSharedType != PTHREAD_PROCESS_PRIVATE)
94 mutex->iState = _EInvalid;
95 _pthread_mutex_t* pMutex = new _pthread_mutex_t;
102 pMutex->iSharedType = attr->iSharedType;
103 pMutex->iMutexType = attr->iMutexType;
104 pMutex->iDataLockCreated = false;
105 pMutex->iSemaphoreCreated = false;
107 if(pMutex->iSignalSemaphore.CreateLocal(1) != KErrNone)
112 pMutex->iSemaphoreCreated = true;
114 if(pMutex->iDataLock.CreateLocal() != KErrNone)
119 pMutex->iDataLockCreated = true;
122 pMutex->iSemaphoreState = SEM_FREE;
123 pMutex->iLockingThread = 0;
124 mutex->iState = _EInitialized;
130 This function is an internal harness function used to resolve the race to dynamically initialize a static mutex
132 bool _InitOnce(pthread_mutex_t* mutex)
135 pthread_mutexattr_t defaultattributes =
136 PTHREAD_MUTEX_ATTRIBUTE_DEFAULT_INITIALIZER;
137 pthread_mutexattr_t recursiveattributes =
138 PTHREAD_MUTEX_ATTRIBUTE_RECURSIVE_INITIALIZER;
139 pthread_mutexattr_t errorcheckattributes =
140 PTHREAD_MUTEX_ATTRIBUTE_ERRORCHECK_INITIALIZER;
142 if(mutex->iState == _EInitialized)
147 mutex->iReentry = 0xBABA;
149 pthread_mutexattr_t* attr;
150 switch(mutex->iState)
152 case _ENeedsNormalInit:
154 attr = &defaultattributes;
158 case _ENeedsRecursiveInit:
160 attr = &recursiveattributes;
164 case _ENeedsErrorCheckInit:
166 attr = &errorcheckattributes;
174 #ifndef NOUSE_INTERNALS
177 // Get the TLS pointer
178 tlsPtr = _pthread_getTls();
187 #ifndef NOUSE_INTERNALS
188 _pthread_atomicMutexLock(tlsPtr);
190 if(mutex->iState != _EInitialized)
192 retval = _mutexCreate(mutex,attr);
194 #ifndef NOUSE_INTERNALS
195 _pthread_atomicMutexUnlock(tlsPtr);
210 This function is an internal function used to provide the POSIX mutex lock
213 int _internalMutexLock(pthread_mutex_t * mutex,const struct timespec *abstime)
215 if( !VALID_MUTEX(mutex) )
220 _pthread_mutex_t* pMutex = mutex->iPtr;
225 switch(pMutex->iMutexType)
227 case PTHREAD_MUTEX_NORMAL:
229 self = pthread_self();
230 pMutex->iDataLock.Wait();
231 if(mutex->iState == _EDestroyed)
233 pMutex->iDataLock.Signal();
236 pMutex->iSemaphoreState++;
237 pMutex->iDataLock.Signal();
239 retval = _doWait(&pMutex->iSignalSemaphore,abstime);
242 pMutex->iDataLock.Wait();
243 if(mutex->iState == _EDestroyed)
245 pMutex->iDataLock.Signal();
248 pMutex->iLockingThread = self;
249 pMutex->iDataLock.Signal();
254 case PTHREAD_MUTEX_RECURSIVE:
257 self = pthread_self();
258 if(pMutex->iLockingThread == self)
260 pMutex->iDataLock.Wait();
261 if(mutex->iState == _EDestroyed)
263 pMutex->iDataLock.Signal();
267 pMutex->iDataLock.Signal();
271 pMutex->iDataLock.Wait();
272 if(mutex->iState == _EDestroyed)
274 pMutex->iDataLock.Signal();
277 pMutex->iSemaphoreState++;
278 pMutex->iDataLock.Signal();
280 retval = _doWait(&pMutex->iSignalSemaphore,abstime);
283 pMutex->iDataLock.Wait();
284 if(mutex->iState == _EDestroyed)
286 pMutex->iDataLock.Signal();
290 pMutex->iLockingThread = self;
291 pMutex->iDataLock.Signal();
297 case PTHREAD_MUTEX_ERRORCHECK:
299 self = pthread_self();
300 if(pMutex->iLockingThread == self)
306 pMutex->iDataLock.Wait();
307 if(mutex->iState == _EDestroyed)
309 pMutex->iDataLock.Signal();
312 pMutex->iSemaphoreState++;
313 pMutex->iDataLock.Signal();
315 retval = _doWait(&pMutex->iSignalSemaphore,abstime);
318 pMutex->iDataLock.Wait();
319 if(mutex->iState == _EDestroyed)
321 pMutex->iDataLock.Signal();
324 pMutex->iLockingThread = self;
325 pMutex->iDataLock.Signal();