HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_RecursiveTimedLock.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_RecursiveTimedLock.h (UT Library, C++)
7  *
8  * COMMENTS: Recursive mutex that supports timedLock(), required
9  * by UT_AbortableLock.
10  *
11  */
12 
13 #ifndef __UT_RECURSIVETIMEDLOCK_H_INCLUDED__
14 #define __UT_RECURSIVETIMEDLOCK_H_INCLUDED__
15 
16 #include "UT_API.h"
17 #include "UT_Assert.h"
18 #include "UT_Lockable.h"
19 #include "UT_NonCopyable.h"
20 #include <SYS/SYS_Types.h>
21 
22 #if defined(USE_PTHREADS) && !defined(MBSD)
23 //
24 // pthread implementation
25 //
26 
27 #include <pthread.h>
28 #include <sys/time.h>
29 #include <errno.h>
30 
31 #if defined(MBSD)
32  #define UT_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
33 #else
34  #define UT_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
35 #endif
36 
38 {
39 public:
41  {
42  pthread_mutexattr_t attr;
43  UT_VERIFY(pthread_mutexattr_init(&attr) == 0);
44  UT_VERIFY(pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE)==0);
45  UT_VERIFY(pthread_mutex_init(&myMutex, &attr) == 0);
46  UT_VERIFY(pthread_mutexattr_destroy(&attr) == 0);
47  }
49  {
50  pthread_mutex_destroy(&myMutex);
51  }
52 
53  bool tryLock()
54  {
55  int res = pthread_mutex_trylock(&myMutex);
56  UT_ASSERT(res == 0 || res == EBUSY);
57  return (res == 0);
58  }
59 
60  void lock()
61  {
62  UT_VERIFY(pthread_mutex_lock(&myMutex) == 0);
63  }
64 
65  bool timedLock(int ms)
66  {
67  const uint64 THOUSAND = 1000;
68  const uint64 MILLION = THOUSAND * THOUSAND;
69  struct timeval now;
70  struct timespec timeout;
71  uint64 usec;
72 
73  gettimeofday(&now, NULL);
74  usec = now.tv_usec + THOUSAND*(ms + now.tv_sec*THOUSAND);
75  timeout.tv_sec = (time_t)(usec / MILLION);
76  timeout.tv_nsec = (long)((usec % MILLION) * THOUSAND);
77 
78  int res = pthread_mutex_timedlock(&myMutex, &timeout);
79  UT_ASSERT(res == 0|| res == ETIMEDOUT);
80  return (res == 0);
81  }
82 
83  void unlock()
84  {
85  UT_VERIFY(pthread_mutex_unlock(&myMutex) == 0);
86  }
87 
88  bool isLocked()
89  {
90  if (tryLock())
91  {
92  unlock();
93  return false;
94  }
95  return true;
96  }
97 
98  /// Class for auto-unlocking
100 
101 private:
102  pthread_mutex_t myMutex;
103 };
104 
105 #elif defined(_WIN32) || defined(MBSD)
106 //
107 // hboost::recursive_timed_mutex is fastest on Windows and OSX,
108 // beats std::recursive_timed_mutex on those platforms.
109 //
110 
111 #include <SYS/SYS_BoostThread.h>
112 
113 /// Lock adapter for boost mutexes
114 template <class HBOOST_MUTEX>
115 class UT_BoostLockable : public UT_Lockable<HBOOST_MUTEX>
116 {
117 public:
118  bool timedLock(int ms)
119  {
121  .timed_lock(hboost::posix_time::milliseconds(ms));
122  }
123 };
124 
125 // Use hboost::recursive_timed_mutex
126 typedef UT_BoostLockable<hboost::recursive_timed_mutex> UT_RecursiveTimedLock;
127 
128 #else
129 //
130 // C++11 standard implementation
131 //
132 // NOTE: Currently unused because:
133 // - It slower than hboost::recursive_timed_mutex on Windows/OSX
134 // (see testut -it TESTUT_BoostThread)
135 // - On gcc 4.8, it's completely broken, only fixed in g++ >= 4.9
136 //
137 
138 #include <chrono>
139 #include <mutex>
140 
141 /// Lock adapter for std mutexes
142 template <class STD_MUTEX>
143 class UT_StdLockable : public UT_Lockable<STD_MUTEX>
144 {
145 public:
146  bool timedLock(int ms)
147  {
149  .try_lock_for(std::chrono::milliseconds(ms));
150  }
151 };
153 
154 #endif
155 
156 #endif // __UT_RECURSIVETIMEDLOCK_H_INCLUDED__
UT_Lock interface adapter for C++11 mutexes.
Definition: UT_Lockable.h:22
MUTEX & mutex()
Definition: UT_Lockable.h:52
unsigned long long uint64
Definition: SYS_Types.h:107
Lock adapter for std mutexes.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
GLbitfield GLuint64 timeout
Definition: glcorearb.h:1598
UT_LockScopeType< UT_Lockable< STD_MUTEX > > Scope
Definition: UT_Lockable.h:29
#define UT_VERIFY(expr)
Definition: UT_Assert.h:148
UT_StdLockable< std::recursive_timed_mutex > UT_RecursiveTimedLock