10b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
20b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// Copyright 2006-2008 Adobe Systems Incorporated
30b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// All Rights Reserved.
40b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener//
50b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// NOTICE:  Adobe permits you to use, modify, and distribute this file in
60b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// accordance with the terms of the Adobe license agreement accompanying it.
70b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
80b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
90b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_mutex.cpp#3 $ */
100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $DateTime: 2012/09/05 12:31:51 $ */
110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $Change: 847652 $ */
120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $Author: tknoll $ */
130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_mutex.h"
150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_assertions.h"
170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_exceptions.h"
180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include <stdlib.h>
200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#if qDNGThreadSafe
240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienernamespace
260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	class InnermostMutexHolder
290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		private:
320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			pthread_key_t fInnermostMutexKey;
340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		public:
360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			InnermostMutexHolder ()
380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				:	fInnermostMutexKey ()
400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				int result = pthread_key_create (&fInnermostMutexKey, NULL);
440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				DNG_ASSERT (result == 0, "pthread_key_create failed.");
460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				if (result != 0)
480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					ThrowProgramError ();
490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			~InnermostMutexHolder ()
530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				pthread_key_delete (fInnermostMutexKey);
560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			void SetInnermostMutex (dng_mutex *mutex)
600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				int result;
630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				result = pthread_setspecific (fInnermostMutexKey, (void *)mutex);
650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				DNG_ASSERT (result == 0, "pthread_setspecific failed.");
670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				#if 0		// Hard failure here was causing crash on quit.
690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				if (result != 0)
710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					ThrowProgramError ();
720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				#endif
740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			dng_mutex *GetInnermostMutex ()
780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				void *result = pthread_getspecific (fInnermostMutexKey);
810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				return reinterpret_cast<dng_mutex *> (result);
830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		};
870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	InnermostMutexHolder gInnermostMutexHolder;
890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#endif
930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_mutex::dng_mutex (const char *mutexName, uint32 mutexLevel)
970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#if qDNGThreadSafe
990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	:	fPthreadMutex		()
1010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fMutexLevel			(mutexLevel)
1020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fRecursiveLockCount (0)
1030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fPrevHeldMutex		(NULL)
1040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fMutexName			(mutexName)
1050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#endif
1070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
1090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#if qDNGThreadSafe
1110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (pthread_mutex_init (&fPthreadMutex, NULL) != 0)
1130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
1140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ThrowMemoryFull ();
1150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
1160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#endif
1180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
1200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
1220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_mutex::~dng_mutex ()
1240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
1250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#if qDNGThreadSafe
1270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	pthread_mutex_destroy (&fPthreadMutex);
1290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#endif
1310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
1330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
1350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_mutex::Lock ()
1370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
1380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#if qDNGThreadSafe
1400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	dng_mutex *innermostMutex = gInnermostMutexHolder.GetInnermostMutex ();
1420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (innermostMutex != NULL)
1440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
1450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (innermostMutex == this)
1470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fRecursiveLockCount++;
1500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return;
1520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		bool lockOrderPreserved = fMutexLevel > innermostMutex->fMutexLevel /* ||
1560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								  (fMutexLevel == innermostMutex->fMutexLevel && innermostMutex < this) */;
1570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (!lockOrderPreserved)
1590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			DNG_REPORT ("Lock ordering violation.");
1620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGDebug
1640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			dng_show_message_f ("This mutex: %s v Innermost mutex: %s",
1660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								this->MutexName (),
1670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								innermostMutex->MutexName ());
1680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
1700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
1740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	pthread_mutex_lock (&fPthreadMutex);
1760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fPrevHeldMutex = innermostMutex;
1780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	gInnermostMutexHolder.SetInnermostMutex (this);
1800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#endif
1820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
1840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
1860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_mutex::Unlock ()
1880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
1890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#if qDNGThreadSafe
1910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	DNG_ASSERT (gInnermostMutexHolder.GetInnermostMutex () == this, "Mutexes unlocked out of order!!!");
1930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fRecursiveLockCount > 0)
1950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
1960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fRecursiveLockCount--;
1980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return;
2000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
2020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	gInnermostMutexHolder.SetInnermostMutex (fPrevHeldMutex);
2040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fPrevHeldMutex = NULL;
2060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	pthread_mutex_unlock (&fPthreadMutex);
2080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#endif
2100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerconst char *dng_mutex::MutexName () const
2160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#if qDNGThreadSafe
2190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fMutexName)
2210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return fMutexName;
2220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	#endif
2240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return "< unknown >";
2260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_lock_mutex::dng_lock_mutex (dng_mutex *mutex)
2320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	:	fMutex (mutex)
2340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fMutex)
2380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fMutex->Lock ();
2390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_lock_mutex::~dng_lock_mutex ()
2450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fMutex)
2480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fMutex->Unlock ();
2490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_unlock_mutex::dng_unlock_mutex (dng_mutex *mutex)
2550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	:	fMutex (mutex)
2570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fMutex)
2610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fMutex->Unlock ();
2620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_unlock_mutex::~dng_unlock_mutex ()
2680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fMutex)
2710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fMutex->Lock ();
2720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#if qDNGThreadSafe
2780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_condition::dng_condition ()
2820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	:	fPthreadCondition ()
2840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	int result;
2880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	result = pthread_cond_init (&fPthreadCondition, NULL);
2900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	DNG_ASSERT (result == 0, "pthread_cond_init failed.");
2920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (result != 0)
2940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
2950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ThrowProgramError ();
2960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
2970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_condition::~dng_condition ()
3030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	pthread_cond_destroy (&fPthreadCondition);
3060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_condition::Wait (dng_mutex &mutex, double timeoutSecs)
3120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	bool timedOut = false;
3150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	dng_mutex *innermostMutex = gInnermostMutexHolder.GetInnermostMutex ();
3170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	DNG_ASSERT (innermostMutex == &mutex, "Attempt to wait on non-innermost mutex.");
3190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	innermostMutex = mutex.fPrevHeldMutex;
3210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	gInnermostMutexHolder.SetInnermostMutex (innermostMutex);
3230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	mutex.fPrevHeldMutex = NULL;
3250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (timeoutSecs < 0)
3270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
3280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		pthread_cond_wait (&fPthreadCondition, &mutex.fPthreadMutex);
3300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
3320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	else
3340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
3350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		struct timespec now;
3370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_pthread_now (&now);
3390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		timeoutSecs += now.tv_sec;
3410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		timeoutSecs += now.tv_nsec / 1000000000.0;
3420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		now.tv_sec  = (long) timeoutSecs;
3440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		now.tv_nsec = (long) ((timeoutSecs - now.tv_sec) * 1000000000);
3450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		timedOut = (pthread_cond_timedwait (&fPthreadCondition, &mutex.fPthreadMutex, &now) == ETIMEDOUT);
3470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
3490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	mutex.fPrevHeldMutex = innermostMutex;
3510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	gInnermostMutexHolder.SetInnermostMutex (&mutex);
3530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return !timedOut;
3550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_condition::Signal ()
3610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	int result;
3640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	result = pthread_cond_signal (&fPthreadCondition);
3660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	DNG_ASSERT (result == 0, "pthread_cond_signal failed.");
3680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (result != 0)
3700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ThrowProgramError ();
3710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_condition::Broadcast ()
3770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	int result;
3800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	result = pthread_cond_broadcast (&fPthreadCondition);
3820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	DNG_ASSERT (result == 0, "pthread_cond_broadcast failed.");
3840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (result != 0)
3860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ThrowProgramError ();
3870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#endif // qDNGThreadSafe
3930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
395