xref: /aosp_15_r20/external/dng_sdk/source/dng_mutex.cpp (revision fd1fabb72dbdf09ea7034f531e6f8e9f57334c8d)
1*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2*fd1fabb7SAndroid Build Coastguard Worker // Copyright 2006-2008 Adobe Systems Incorporated
3*fd1fabb7SAndroid Build Coastguard Worker // All Rights Reserved.
4*fd1fabb7SAndroid Build Coastguard Worker //
5*fd1fabb7SAndroid Build Coastguard Worker // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6*fd1fabb7SAndroid Build Coastguard Worker // accordance with the terms of the Adobe license agreement accompanying it.
7*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
8*fd1fabb7SAndroid Build Coastguard Worker 
9*fd1fabb7SAndroid Build Coastguard Worker /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_mutex.cpp#3 $ */
10*fd1fabb7SAndroid Build Coastguard Worker /* $DateTime: 2012/09/05 12:31:51 $ */
11*fd1fabb7SAndroid Build Coastguard Worker /* $Change: 847652 $ */
12*fd1fabb7SAndroid Build Coastguard Worker /* $Author: tknoll $ */
13*fd1fabb7SAndroid Build Coastguard Worker 
14*fd1fabb7SAndroid Build Coastguard Worker #include "dng_mutex.h"
15*fd1fabb7SAndroid Build Coastguard Worker 
16*fd1fabb7SAndroid Build Coastguard Worker #include "dng_assertions.h"
17*fd1fabb7SAndroid Build Coastguard Worker #include "dng_exceptions.h"
18*fd1fabb7SAndroid Build Coastguard Worker 
19*fd1fabb7SAndroid Build Coastguard Worker #include <stdlib.h>
20*fd1fabb7SAndroid Build Coastguard Worker 
21*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
22*fd1fabb7SAndroid Build Coastguard Worker 
23*fd1fabb7SAndroid Build Coastguard Worker #if qDNGThreadSafe
24*fd1fabb7SAndroid Build Coastguard Worker 
25*fd1fabb7SAndroid Build Coastguard Worker namespace
26*fd1fabb7SAndroid Build Coastguard Worker 	{
27*fd1fabb7SAndroid Build Coastguard Worker 
28*fd1fabb7SAndroid Build Coastguard Worker 	class InnermostMutexHolder
29*fd1fabb7SAndroid Build Coastguard Worker 		{
30*fd1fabb7SAndroid Build Coastguard Worker 
31*fd1fabb7SAndroid Build Coastguard Worker 		private:
32*fd1fabb7SAndroid Build Coastguard Worker 
33*fd1fabb7SAndroid Build Coastguard Worker 			pthread_key_t fInnermostMutexKey;
34*fd1fabb7SAndroid Build Coastguard Worker 
35*fd1fabb7SAndroid Build Coastguard Worker 		public:
36*fd1fabb7SAndroid Build Coastguard Worker 
InnermostMutexHolder()37*fd1fabb7SAndroid Build Coastguard Worker 			InnermostMutexHolder ()
38*fd1fabb7SAndroid Build Coastguard Worker 
39*fd1fabb7SAndroid Build Coastguard Worker 				:	fInnermostMutexKey ()
40*fd1fabb7SAndroid Build Coastguard Worker 
41*fd1fabb7SAndroid Build Coastguard Worker 				{
42*fd1fabb7SAndroid Build Coastguard Worker 
43*fd1fabb7SAndroid Build Coastguard Worker 				int result = pthread_key_create (&fInnermostMutexKey, NULL);
44*fd1fabb7SAndroid Build Coastguard Worker 
45*fd1fabb7SAndroid Build Coastguard Worker 				DNG_ASSERT (result == 0, "pthread_key_create failed.");
46*fd1fabb7SAndroid Build Coastguard Worker 
47*fd1fabb7SAndroid Build Coastguard Worker 				if (result != 0)
48*fd1fabb7SAndroid Build Coastguard Worker 					ThrowProgramError ();
49*fd1fabb7SAndroid Build Coastguard Worker 
50*fd1fabb7SAndroid Build Coastguard Worker 				}
51*fd1fabb7SAndroid Build Coastguard Worker 
~InnermostMutexHolder()52*fd1fabb7SAndroid Build Coastguard Worker 			~InnermostMutexHolder ()
53*fd1fabb7SAndroid Build Coastguard Worker 				{
54*fd1fabb7SAndroid Build Coastguard Worker 
55*fd1fabb7SAndroid Build Coastguard Worker 				pthread_key_delete (fInnermostMutexKey);
56*fd1fabb7SAndroid Build Coastguard Worker 
57*fd1fabb7SAndroid Build Coastguard Worker 				}
58*fd1fabb7SAndroid Build Coastguard Worker 
SetInnermostMutex(dng_mutex * mutex)59*fd1fabb7SAndroid Build Coastguard Worker 			void SetInnermostMutex (dng_mutex *mutex)
60*fd1fabb7SAndroid Build Coastguard Worker 				{
61*fd1fabb7SAndroid Build Coastguard Worker 
62*fd1fabb7SAndroid Build Coastguard Worker 				int result;
63*fd1fabb7SAndroid Build Coastguard Worker 
64*fd1fabb7SAndroid Build Coastguard Worker 				result = pthread_setspecific (fInnermostMutexKey, (void *)mutex);
65*fd1fabb7SAndroid Build Coastguard Worker 
66*fd1fabb7SAndroid Build Coastguard Worker 				DNG_ASSERT (result == 0, "pthread_setspecific failed.");
67*fd1fabb7SAndroid Build Coastguard Worker 
68*fd1fabb7SAndroid Build Coastguard Worker 				#if 0		// Hard failure here was causing crash on quit.
69*fd1fabb7SAndroid Build Coastguard Worker 
70*fd1fabb7SAndroid Build Coastguard Worker 				if (result != 0)
71*fd1fabb7SAndroid Build Coastguard Worker 					ThrowProgramError ();
72*fd1fabb7SAndroid Build Coastguard Worker 
73*fd1fabb7SAndroid Build Coastguard Worker 				#endif
74*fd1fabb7SAndroid Build Coastguard Worker 
75*fd1fabb7SAndroid Build Coastguard Worker 				}
76*fd1fabb7SAndroid Build Coastguard Worker 
GetInnermostMutex()77*fd1fabb7SAndroid Build Coastguard Worker 			dng_mutex *GetInnermostMutex ()
78*fd1fabb7SAndroid Build Coastguard Worker 				{
79*fd1fabb7SAndroid Build Coastguard Worker 
80*fd1fabb7SAndroid Build Coastguard Worker 				void *result = pthread_getspecific (fInnermostMutexKey);
81*fd1fabb7SAndroid Build Coastguard Worker 
82*fd1fabb7SAndroid Build Coastguard Worker 				return reinterpret_cast<dng_mutex *> (result);
83*fd1fabb7SAndroid Build Coastguard Worker 
84*fd1fabb7SAndroid Build Coastguard Worker 				}
85*fd1fabb7SAndroid Build Coastguard Worker 
86*fd1fabb7SAndroid Build Coastguard Worker 		};
87*fd1fabb7SAndroid Build Coastguard Worker 
88*fd1fabb7SAndroid Build Coastguard Worker 	InnermostMutexHolder gInnermostMutexHolder;
89*fd1fabb7SAndroid Build Coastguard Worker 
90*fd1fabb7SAndroid Build Coastguard Worker 	}
91*fd1fabb7SAndroid Build Coastguard Worker 
92*fd1fabb7SAndroid Build Coastguard Worker #endif
93*fd1fabb7SAndroid Build Coastguard Worker 
94*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
95*fd1fabb7SAndroid Build Coastguard Worker 
dng_mutex(const char * mutexName,uint32 mutexLevel)96*fd1fabb7SAndroid Build Coastguard Worker dng_mutex::dng_mutex (const char *mutexName, uint32 mutexLevel)
97*fd1fabb7SAndroid Build Coastguard Worker 
98*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGThreadSafe
99*fd1fabb7SAndroid Build Coastguard Worker 
100*fd1fabb7SAndroid Build Coastguard Worker 	:	fPthreadMutex		()
101*fd1fabb7SAndroid Build Coastguard Worker 	,	fMutexLevel			(mutexLevel)
102*fd1fabb7SAndroid Build Coastguard Worker 	,	fRecursiveLockCount (0)
103*fd1fabb7SAndroid Build Coastguard Worker 	,	fPrevHeldMutex		(NULL)
104*fd1fabb7SAndroid Build Coastguard Worker 	,	fMutexName			(mutexName)
105*fd1fabb7SAndroid Build Coastguard Worker 
106*fd1fabb7SAndroid Build Coastguard Worker 	#endif
107*fd1fabb7SAndroid Build Coastguard Worker 
108*fd1fabb7SAndroid Build Coastguard Worker 	{
109*fd1fabb7SAndroid Build Coastguard Worker 
110*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGThreadSafe
111*fd1fabb7SAndroid Build Coastguard Worker 
112*fd1fabb7SAndroid Build Coastguard Worker 	if (pthread_mutex_init (&fPthreadMutex, NULL) != 0)
113*fd1fabb7SAndroid Build Coastguard Worker 		{
114*fd1fabb7SAndroid Build Coastguard Worker 		ThrowMemoryFull ();
115*fd1fabb7SAndroid Build Coastguard Worker 		}
116*fd1fabb7SAndroid Build Coastguard Worker 
117*fd1fabb7SAndroid Build Coastguard Worker 	#endif
118*fd1fabb7SAndroid Build Coastguard Worker 
119*fd1fabb7SAndroid Build Coastguard Worker 	}
120*fd1fabb7SAndroid Build Coastguard Worker 
121*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
122*fd1fabb7SAndroid Build Coastguard Worker 
~dng_mutex()123*fd1fabb7SAndroid Build Coastguard Worker dng_mutex::~dng_mutex ()
124*fd1fabb7SAndroid Build Coastguard Worker 	{
125*fd1fabb7SAndroid Build Coastguard Worker 
126*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGThreadSafe
127*fd1fabb7SAndroid Build Coastguard Worker 
128*fd1fabb7SAndroid Build Coastguard Worker 	pthread_mutex_destroy (&fPthreadMutex);
129*fd1fabb7SAndroid Build Coastguard Worker 
130*fd1fabb7SAndroid Build Coastguard Worker 	#endif
131*fd1fabb7SAndroid Build Coastguard Worker 
132*fd1fabb7SAndroid Build Coastguard Worker 	}
133*fd1fabb7SAndroid Build Coastguard Worker 
134*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
135*fd1fabb7SAndroid Build Coastguard Worker 
Lock()136*fd1fabb7SAndroid Build Coastguard Worker void dng_mutex::Lock ()
137*fd1fabb7SAndroid Build Coastguard Worker 	{
138*fd1fabb7SAndroid Build Coastguard Worker 
139*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGThreadSafe
140*fd1fabb7SAndroid Build Coastguard Worker 
141*fd1fabb7SAndroid Build Coastguard Worker 	dng_mutex *innermostMutex = gInnermostMutexHolder.GetInnermostMutex ();
142*fd1fabb7SAndroid Build Coastguard Worker 
143*fd1fabb7SAndroid Build Coastguard Worker 	if (innermostMutex != NULL)
144*fd1fabb7SAndroid Build Coastguard Worker 		{
145*fd1fabb7SAndroid Build Coastguard Worker 
146*fd1fabb7SAndroid Build Coastguard Worker 		if (innermostMutex == this)
147*fd1fabb7SAndroid Build Coastguard Worker 			{
148*fd1fabb7SAndroid Build Coastguard Worker 
149*fd1fabb7SAndroid Build Coastguard Worker 			fRecursiveLockCount++;
150*fd1fabb7SAndroid Build Coastguard Worker 
151*fd1fabb7SAndroid Build Coastguard Worker 			return;
152*fd1fabb7SAndroid Build Coastguard Worker 
153*fd1fabb7SAndroid Build Coastguard Worker 			}
154*fd1fabb7SAndroid Build Coastguard Worker 
155*fd1fabb7SAndroid Build Coastguard Worker 		bool lockOrderPreserved = fMutexLevel > innermostMutex->fMutexLevel /* ||
156*fd1fabb7SAndroid Build Coastguard Worker 								  (fMutexLevel == innermostMutex->fMutexLevel && innermostMutex < this) */;
157*fd1fabb7SAndroid Build Coastguard Worker 
158*fd1fabb7SAndroid Build Coastguard Worker 		if (!lockOrderPreserved)
159*fd1fabb7SAndroid Build Coastguard Worker 			{
160*fd1fabb7SAndroid Build Coastguard Worker 
161*fd1fabb7SAndroid Build Coastguard Worker 			DNG_REPORT ("Lock ordering violation.");
162*fd1fabb7SAndroid Build Coastguard Worker 
163*fd1fabb7SAndroid Build Coastguard Worker 			#if qDNGDebug
164*fd1fabb7SAndroid Build Coastguard Worker 
165*fd1fabb7SAndroid Build Coastguard Worker 			dng_show_message_f ("This mutex: %s v Innermost mutex: %s",
166*fd1fabb7SAndroid Build Coastguard Worker 								this->MutexName (),
167*fd1fabb7SAndroid Build Coastguard Worker 								innermostMutex->MutexName ());
168*fd1fabb7SAndroid Build Coastguard Worker 
169*fd1fabb7SAndroid Build Coastguard Worker 			#endif
170*fd1fabb7SAndroid Build Coastguard Worker 
171*fd1fabb7SAndroid Build Coastguard Worker 			}
172*fd1fabb7SAndroid Build Coastguard Worker 
173*fd1fabb7SAndroid Build Coastguard Worker 		}
174*fd1fabb7SAndroid Build Coastguard Worker 
175*fd1fabb7SAndroid Build Coastguard Worker 	pthread_mutex_lock (&fPthreadMutex);
176*fd1fabb7SAndroid Build Coastguard Worker 
177*fd1fabb7SAndroid Build Coastguard Worker 	fPrevHeldMutex = innermostMutex;
178*fd1fabb7SAndroid Build Coastguard Worker 
179*fd1fabb7SAndroid Build Coastguard Worker 	gInnermostMutexHolder.SetInnermostMutex (this);
180*fd1fabb7SAndroid Build Coastguard Worker 
181*fd1fabb7SAndroid Build Coastguard Worker 	#endif
182*fd1fabb7SAndroid Build Coastguard Worker 
183*fd1fabb7SAndroid Build Coastguard Worker 	}
184*fd1fabb7SAndroid Build Coastguard Worker 
185*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
186*fd1fabb7SAndroid Build Coastguard Worker 
Unlock()187*fd1fabb7SAndroid Build Coastguard Worker void dng_mutex::Unlock ()
188*fd1fabb7SAndroid Build Coastguard Worker 	{
189*fd1fabb7SAndroid Build Coastguard Worker 
190*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGThreadSafe
191*fd1fabb7SAndroid Build Coastguard Worker 
192*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (gInnermostMutexHolder.GetInnermostMutex () == this, "Mutexes unlocked out of order!!!");
193*fd1fabb7SAndroid Build Coastguard Worker 
194*fd1fabb7SAndroid Build Coastguard Worker 	if (fRecursiveLockCount > 0)
195*fd1fabb7SAndroid Build Coastguard Worker 		{
196*fd1fabb7SAndroid Build Coastguard Worker 
197*fd1fabb7SAndroid Build Coastguard Worker 		fRecursiveLockCount--;
198*fd1fabb7SAndroid Build Coastguard Worker 
199*fd1fabb7SAndroid Build Coastguard Worker 		return;
200*fd1fabb7SAndroid Build Coastguard Worker 
201*fd1fabb7SAndroid Build Coastguard Worker 		}
202*fd1fabb7SAndroid Build Coastguard Worker 
203*fd1fabb7SAndroid Build Coastguard Worker 	gInnermostMutexHolder.SetInnermostMutex (fPrevHeldMutex);
204*fd1fabb7SAndroid Build Coastguard Worker 
205*fd1fabb7SAndroid Build Coastguard Worker 	fPrevHeldMutex = NULL;
206*fd1fabb7SAndroid Build Coastguard Worker 
207*fd1fabb7SAndroid Build Coastguard Worker 	pthread_mutex_unlock (&fPthreadMutex);
208*fd1fabb7SAndroid Build Coastguard Worker 
209*fd1fabb7SAndroid Build Coastguard Worker 	#endif
210*fd1fabb7SAndroid Build Coastguard Worker 
211*fd1fabb7SAndroid Build Coastguard Worker 	}
212*fd1fabb7SAndroid Build Coastguard Worker 
213*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
214*fd1fabb7SAndroid Build Coastguard Worker 
MutexName() const215*fd1fabb7SAndroid Build Coastguard Worker const char *dng_mutex::MutexName () const
216*fd1fabb7SAndroid Build Coastguard Worker 	{
217*fd1fabb7SAndroid Build Coastguard Worker 
218*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGThreadSafe
219*fd1fabb7SAndroid Build Coastguard Worker 
220*fd1fabb7SAndroid Build Coastguard Worker 	if (fMutexName)
221*fd1fabb7SAndroid Build Coastguard Worker 		return fMutexName;
222*fd1fabb7SAndroid Build Coastguard Worker 
223*fd1fabb7SAndroid Build Coastguard Worker 	#endif
224*fd1fabb7SAndroid Build Coastguard Worker 
225*fd1fabb7SAndroid Build Coastguard Worker 	return "< unknown >";
226*fd1fabb7SAndroid Build Coastguard Worker 
227*fd1fabb7SAndroid Build Coastguard Worker 	}
228*fd1fabb7SAndroid Build Coastguard Worker 
229*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
230*fd1fabb7SAndroid Build Coastguard Worker 
dng_lock_mutex(dng_mutex * mutex)231*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex::dng_lock_mutex (dng_mutex *mutex)
232*fd1fabb7SAndroid Build Coastguard Worker 
233*fd1fabb7SAndroid Build Coastguard Worker 	:	fMutex (mutex)
234*fd1fabb7SAndroid Build Coastguard Worker 
235*fd1fabb7SAndroid Build Coastguard Worker 	{
236*fd1fabb7SAndroid Build Coastguard Worker 
237*fd1fabb7SAndroid Build Coastguard Worker 	if (fMutex)
238*fd1fabb7SAndroid Build Coastguard Worker 		fMutex->Lock ();
239*fd1fabb7SAndroid Build Coastguard Worker 
240*fd1fabb7SAndroid Build Coastguard Worker 	}
241*fd1fabb7SAndroid Build Coastguard Worker 
242*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
243*fd1fabb7SAndroid Build Coastguard Worker 
~dng_lock_mutex()244*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex::~dng_lock_mutex ()
245*fd1fabb7SAndroid Build Coastguard Worker 	{
246*fd1fabb7SAndroid Build Coastguard Worker 
247*fd1fabb7SAndroid Build Coastguard Worker 	if (fMutex)
248*fd1fabb7SAndroid Build Coastguard Worker 		fMutex->Unlock ();
249*fd1fabb7SAndroid Build Coastguard Worker 
250*fd1fabb7SAndroid Build Coastguard Worker 	}
251*fd1fabb7SAndroid Build Coastguard Worker 
252*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
253*fd1fabb7SAndroid Build Coastguard Worker 
dng_unlock_mutex(dng_mutex * mutex)254*fd1fabb7SAndroid Build Coastguard Worker dng_unlock_mutex::dng_unlock_mutex (dng_mutex *mutex)
255*fd1fabb7SAndroid Build Coastguard Worker 
256*fd1fabb7SAndroid Build Coastguard Worker 	:	fMutex (mutex)
257*fd1fabb7SAndroid Build Coastguard Worker 
258*fd1fabb7SAndroid Build Coastguard Worker 	{
259*fd1fabb7SAndroid Build Coastguard Worker 
260*fd1fabb7SAndroid Build Coastguard Worker 	if (fMutex)
261*fd1fabb7SAndroid Build Coastguard Worker 		fMutex->Unlock ();
262*fd1fabb7SAndroid Build Coastguard Worker 
263*fd1fabb7SAndroid Build Coastguard Worker 	}
264*fd1fabb7SAndroid Build Coastguard Worker 
265*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
266*fd1fabb7SAndroid Build Coastguard Worker 
~dng_unlock_mutex()267*fd1fabb7SAndroid Build Coastguard Worker dng_unlock_mutex::~dng_unlock_mutex ()
268*fd1fabb7SAndroid Build Coastguard Worker 	{
269*fd1fabb7SAndroid Build Coastguard Worker 
270*fd1fabb7SAndroid Build Coastguard Worker 	if (fMutex)
271*fd1fabb7SAndroid Build Coastguard Worker 		fMutex->Lock ();
272*fd1fabb7SAndroid Build Coastguard Worker 
273*fd1fabb7SAndroid Build Coastguard Worker 	}
274*fd1fabb7SAndroid Build Coastguard Worker 
275*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
276*fd1fabb7SAndroid Build Coastguard Worker 
277*fd1fabb7SAndroid Build Coastguard Worker #if qDNGThreadSafe
278*fd1fabb7SAndroid Build Coastguard Worker 
279*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
280*fd1fabb7SAndroid Build Coastguard Worker 
dng_condition()281*fd1fabb7SAndroid Build Coastguard Worker dng_condition::dng_condition ()
282*fd1fabb7SAndroid Build Coastguard Worker 
283*fd1fabb7SAndroid Build Coastguard Worker 	:	fPthreadCondition ()
284*fd1fabb7SAndroid Build Coastguard Worker 
285*fd1fabb7SAndroid Build Coastguard Worker 	{
286*fd1fabb7SAndroid Build Coastguard Worker 
287*fd1fabb7SAndroid Build Coastguard Worker 	int result;
288*fd1fabb7SAndroid Build Coastguard Worker 
289*fd1fabb7SAndroid Build Coastguard Worker 	result = pthread_cond_init (&fPthreadCondition, NULL);
290*fd1fabb7SAndroid Build Coastguard Worker 
291*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (result == 0, "pthread_cond_init failed.");
292*fd1fabb7SAndroid Build Coastguard Worker 
293*fd1fabb7SAndroid Build Coastguard Worker 	if (result != 0)
294*fd1fabb7SAndroid Build Coastguard Worker 		{
295*fd1fabb7SAndroid Build Coastguard Worker 		ThrowProgramError ();
296*fd1fabb7SAndroid Build Coastguard Worker 		}
297*fd1fabb7SAndroid Build Coastguard Worker 
298*fd1fabb7SAndroid Build Coastguard Worker 	}
299*fd1fabb7SAndroid Build Coastguard Worker 
300*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
301*fd1fabb7SAndroid Build Coastguard Worker 
~dng_condition()302*fd1fabb7SAndroid Build Coastguard Worker dng_condition::~dng_condition ()
303*fd1fabb7SAndroid Build Coastguard Worker 	{
304*fd1fabb7SAndroid Build Coastguard Worker 
305*fd1fabb7SAndroid Build Coastguard Worker 	pthread_cond_destroy (&fPthreadCondition);
306*fd1fabb7SAndroid Build Coastguard Worker 
307*fd1fabb7SAndroid Build Coastguard Worker 	}
308*fd1fabb7SAndroid Build Coastguard Worker 
309*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
310*fd1fabb7SAndroid Build Coastguard Worker 
Wait(dng_mutex & mutex,double timeoutSecs)311*fd1fabb7SAndroid Build Coastguard Worker bool dng_condition::Wait (dng_mutex &mutex, double timeoutSecs)
312*fd1fabb7SAndroid Build Coastguard Worker 	{
313*fd1fabb7SAndroid Build Coastguard Worker 
314*fd1fabb7SAndroid Build Coastguard Worker 	bool timedOut = false;
315*fd1fabb7SAndroid Build Coastguard Worker 
316*fd1fabb7SAndroid Build Coastguard Worker 	dng_mutex *innermostMutex = gInnermostMutexHolder.GetInnermostMutex ();
317*fd1fabb7SAndroid Build Coastguard Worker 
318*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (innermostMutex == &mutex, "Attempt to wait on non-innermost mutex.");
319*fd1fabb7SAndroid Build Coastguard Worker 
320*fd1fabb7SAndroid Build Coastguard Worker 	innermostMutex = mutex.fPrevHeldMutex;
321*fd1fabb7SAndroid Build Coastguard Worker 
322*fd1fabb7SAndroid Build Coastguard Worker 	gInnermostMutexHolder.SetInnermostMutex (innermostMutex);
323*fd1fabb7SAndroid Build Coastguard Worker 
324*fd1fabb7SAndroid Build Coastguard Worker 	mutex.fPrevHeldMutex = NULL;
325*fd1fabb7SAndroid Build Coastguard Worker 
326*fd1fabb7SAndroid Build Coastguard Worker 	if (timeoutSecs < 0)
327*fd1fabb7SAndroid Build Coastguard Worker 		{
328*fd1fabb7SAndroid Build Coastguard Worker 
329*fd1fabb7SAndroid Build Coastguard Worker 		pthread_cond_wait (&fPthreadCondition, &mutex.fPthreadMutex);
330*fd1fabb7SAndroid Build Coastguard Worker 
331*fd1fabb7SAndroid Build Coastguard Worker 		}
332*fd1fabb7SAndroid Build Coastguard Worker 
333*fd1fabb7SAndroid Build Coastguard Worker 	else
334*fd1fabb7SAndroid Build Coastguard Worker 		{
335*fd1fabb7SAndroid Build Coastguard Worker 
336*fd1fabb7SAndroid Build Coastguard Worker 		struct timespec now;
337*fd1fabb7SAndroid Build Coastguard Worker 
338*fd1fabb7SAndroid Build Coastguard Worker 		dng_pthread_now (&now);
339*fd1fabb7SAndroid Build Coastguard Worker 
340*fd1fabb7SAndroid Build Coastguard Worker 		timeoutSecs += now.tv_sec;
341*fd1fabb7SAndroid Build Coastguard Worker 		timeoutSecs += now.tv_nsec / 1000000000.0;
342*fd1fabb7SAndroid Build Coastguard Worker 
343*fd1fabb7SAndroid Build Coastguard Worker 		now.tv_sec  = (long) timeoutSecs;
344*fd1fabb7SAndroid Build Coastguard Worker 		now.tv_nsec = (long) ((timeoutSecs - now.tv_sec) * 1000000000);
345*fd1fabb7SAndroid Build Coastguard Worker 
346*fd1fabb7SAndroid Build Coastguard Worker 		timedOut = (pthread_cond_timedwait (&fPthreadCondition, &mutex.fPthreadMutex, &now) == ETIMEDOUT);
347*fd1fabb7SAndroid Build Coastguard Worker 
348*fd1fabb7SAndroid Build Coastguard Worker 		}
349*fd1fabb7SAndroid Build Coastguard Worker 
350*fd1fabb7SAndroid Build Coastguard Worker 	mutex.fPrevHeldMutex = innermostMutex;
351*fd1fabb7SAndroid Build Coastguard Worker 
352*fd1fabb7SAndroid Build Coastguard Worker 	gInnermostMutexHolder.SetInnermostMutex (&mutex);
353*fd1fabb7SAndroid Build Coastguard Worker 
354*fd1fabb7SAndroid Build Coastguard Worker 	return !timedOut;
355*fd1fabb7SAndroid Build Coastguard Worker 
356*fd1fabb7SAndroid Build Coastguard Worker 	}
357*fd1fabb7SAndroid Build Coastguard Worker 
358*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
359*fd1fabb7SAndroid Build Coastguard Worker 
Signal()360*fd1fabb7SAndroid Build Coastguard Worker void dng_condition::Signal ()
361*fd1fabb7SAndroid Build Coastguard Worker 	{
362*fd1fabb7SAndroid Build Coastguard Worker 
363*fd1fabb7SAndroid Build Coastguard Worker 	int result;
364*fd1fabb7SAndroid Build Coastguard Worker 
365*fd1fabb7SAndroid Build Coastguard Worker 	result = pthread_cond_signal (&fPthreadCondition);
366*fd1fabb7SAndroid Build Coastguard Worker 
367*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (result == 0, "pthread_cond_signal failed.");
368*fd1fabb7SAndroid Build Coastguard Worker 
369*fd1fabb7SAndroid Build Coastguard Worker 	if (result != 0)
370*fd1fabb7SAndroid Build Coastguard Worker 		ThrowProgramError ();
371*fd1fabb7SAndroid Build Coastguard Worker 
372*fd1fabb7SAndroid Build Coastguard Worker 	}
373*fd1fabb7SAndroid Build Coastguard Worker 
374*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
375*fd1fabb7SAndroid Build Coastguard Worker 
Broadcast()376*fd1fabb7SAndroid Build Coastguard Worker void dng_condition::Broadcast ()
377*fd1fabb7SAndroid Build Coastguard Worker 	{
378*fd1fabb7SAndroid Build Coastguard Worker 
379*fd1fabb7SAndroid Build Coastguard Worker 	int result;
380*fd1fabb7SAndroid Build Coastguard Worker 
381*fd1fabb7SAndroid Build Coastguard Worker 	result = pthread_cond_broadcast (&fPthreadCondition);
382*fd1fabb7SAndroid Build Coastguard Worker 
383*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (result == 0, "pthread_cond_broadcast failed.");
384*fd1fabb7SAndroid Build Coastguard Worker 
385*fd1fabb7SAndroid Build Coastguard Worker 	if (result != 0)
386*fd1fabb7SAndroid Build Coastguard Worker 		ThrowProgramError ();
387*fd1fabb7SAndroid Build Coastguard Worker 
388*fd1fabb7SAndroid Build Coastguard Worker 	}
389*fd1fabb7SAndroid Build Coastguard Worker 
390*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
391*fd1fabb7SAndroid Build Coastguard Worker 
392*fd1fabb7SAndroid Build Coastguard Worker #endif // qDNGThreadSafe
393*fd1fabb7SAndroid Build Coastguard Worker 
394*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
395