1 /*****************************************************************************/
2 // Copyright 2006-2019 Adobe Systems Incorporated
3 // All Rights Reserved.
4 //
5 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6 // accordance with the terms of the Adobe license agreement accompanying it.
7 /*****************************************************************************/
8 
9 #ifndef __dng_mutex__
10 #define __dng_mutex__
11 
12 /******************************************************************************/
13 
14 #include "dng_flags.h"
15 #include "dng_types.h"
16 #include "dng_uncopyable.h"
17 
18 #if qDNGThreadSafe
19 #include "dng_pthread.h"
20 #endif
21 
22 #include <mutex>
23 
24 typedef std::mutex					 dng_std_mutex;
25 typedef std::lock_guard<std::mutex>	 dng_lock_std_mutex;
26 typedef std::unique_lock<std::mutex> dng_unique_lock;
27 
28 // We should try to phase out use of dng_mutex over time.
29 //
30 // Note that dng_mutex differs from dng_std_mutex (std::mutex) in that
31 // dng_mutex supports recursive locking (hierarchical mutex).
32 
33 /******************************************************************************/
34 
35 class dng_mutex: private dng_uncopyable
36 	{
37 
38 	public:
39 
40 		enum
41 			{
42 			kDNGMutexLevelLeaf   = 0x70000000u,
43             kDNGMutexLevelIgnore = 0x7FFFFFFFu
44 			};
45 
46 		dng_mutex (const char *mutexName,
47 				   uint32 mutexLevel = kDNGMutexLevelLeaf);
48 
49 		virtual ~dng_mutex ();
50 
51 		void Lock ();
52 
53 		void Unlock ();
54 
55 		const char *MutexName () const;
56 
57 	protected:
58 
59 		#if qDNGThreadSafe
60 
61 		pthread_mutex_t fPthreadMutex;
62 
63 		const uint32 fMutexLevel;
64 
65 		uint32 fRecursiveLockCount;
66 
67 		dng_mutex *fPrevHeldMutex;
68 
69 		const char * const fMutexName;
70 
71 		friend class dng_condition;
72 
73 		#endif
74 
75 	};
76 
77 /*****************************************************************************/
78 
79 class dng_lock_mutex: private dng_uncopyable
80 	{
81 
82 	private:
83 
84 		dng_mutex *fMutex;
85 
86 	public:
87 
88 		dng_lock_mutex (dng_mutex *mutex);
89 
90 		dng_lock_mutex (dng_mutex &mutex);
91 
92 		~dng_lock_mutex ();
93 
94 	};
95 
96 /*****************************************************************************/
97 
98 class dng_unlock_mutex: private dng_uncopyable
99 	{
100 
101 	private:
102 
103 		dng_mutex *fMutex;
104 
105 	public:
106 
107 		dng_unlock_mutex (dng_mutex *mutex);
108 
109 		dng_unlock_mutex (dng_mutex &mutex);
110 
111 		~dng_unlock_mutex ();
112 
113 	};
114 
115 /*****************************************************************************/
116 
117 class dng_condition: private dng_uncopyable
118 	{
119 
120 	public:
121 
122 		dng_condition ();
123 
124 		~dng_condition ();
125 
126 		bool Wait (dng_mutex &mutex, double timeoutSecs = -1.0);
127 
128 		void Signal ();
129 
130 		void Broadcast ();
131 
132 	protected:
133 
134 
135 #if qDNGThreadSafe
136 		pthread_cond_t fPthreadCondition;
137 #endif // qDNGThreadSafe
138 
139 	};
140 
141 /*****************************************************************************/
142 
143 #endif
144 
145 /*****************************************************************************/
146