Mobile API Reference  MicroStrategy 2019
InprocessRecursiveMutex.h
Go to the documentation of this file.
1 //==============================================================================================
2 // FILENAME : InprocessRecursiveMutex.h
3 // AUTHOR : vovechkin
4 // CREATION : 2004-06-11
5 // Copyright (C) MicroStrategy Incorporated 2004
6 //==============================================================================================
7 #ifndef MSynch_InprocessRecursiveMutex_h
8 #define MSynch_InprocessRecursiveMutex_h
9 
10 #include "PDCHeader/PDCerrno.h"
11 #include "PDCHeader/PDCpthread.h"
12 #include "Base/Defines/Asserte.h"
13 #if defined(_NO_EXCEPTION)
14 #include <stdio.h>
15 #endif
16 
17 namespace MSynch
18 {
26  {
27  public:
29  inline ~InprocessRecursiveMutex() throw();
30 
31  class SmartLock
32  {
33  public:
34 
35  inline SmartLock(InprocessRecursiveMutex& irMutex);
36  inline ~SmartLock() throw();
37 
38  void Lock()
39  {
40  mrMyMutex.Lock();
41  _ASSERT(mIsLocked == false);
42  mIsLocked = true;
43  }
44 
45  void Unlock() throw()
46  {
47  _ASSERT(mIsLocked == true);
48  mIsLocked = false;
49  mrMyMutex.Unlock();
50  }
51 
52 #ifndef WIN32
53  inline void WaitUntilSpuriouslyWokenUp(
55  pthread_cond_t& irConditionalVariable) const;
56 
60  pthread_cond_t& irConditionalVariable,
61  const struct timespec& irAbsoluteTimeout) const;
62 #endif // WIN32
63 
64  private:
65 
66  bool mIsLocked;
67  InprocessRecursiveMutex& mrMyMutex;
68  };
69 
70  public:
71  inline void Lock();
72  inline bool Lock_NoWait();
73  inline void Unlock() throw();
74 
75  private:
76  friend class CriticalSectionImpl;
77  friend class SmartLock;
79 
80  pthread_mutex_t mMutex;
81  };
82 }
83 
85 //
86 // MSynch::InprocessRecursiveMutex
87 //
89 
91 {
92  const int lResult = ::pthread_mutex_destroy(&mMutex);
93 
94  // can't throw
95  _ASSERT(lResult == 0);
96 
97 }
98 
100 {
101  const int lResult = ::pthread_mutex_lock(&mMutex);
102 
103  if (lResult != 0)
104  {
105  // pthread_mutex_lock will fail only if something
106  // is seriously wrong, such as:
107  // 1. this pointer is wrong
108  // 2. mMutex is corrupt
109  // 3. mMutex is not recursive
110  _ASSERT(false);
111 #if !defined(_NO_EXCEPTION)
112  throw ("::pthread_mutex_lock failed");
113 #else
114  printf("%s\n","MSynch::InprocessRecursiveMutex::Lock: ::pthread_mutex_lock failed");
115  return;
116 #endif
117  }
118 
119 }
120 
122 {
123  const int lResult = ::pthread_mutex_trylock(&mMutex);
124 
125  if (lResult == EBUSY)
126  {
127  return false;
128  }
129 
130  if (lResult != 0)
131  {
132  // pthread_mutex_lock will fail only if something
133  // is seriously wrong, such as:
134  // 1. this pointer is wrong
135  // 2. mMutex is corrupt
136  // 3. mMutex is not recursive
137  _ASSERT(false);
138 #if !defined(_NO_EXCEPTION)
139  throw ("::pthread_mutex_trylock failed");
140 #else
141  printf("%s\n","MSynch::InprocessRecursiveMutex::Lock_NoWait: ::pthread_mutex_trylock failed");
142  return false;
143 #endif
144  }
145 
146  return true;
147 }
148 
150 {
151 
152  const int lResult = ::pthread_mutex_unlock(&mMutex);
153 
154  // this assertion may fail if:
155  // 1. the mMutex is corrupt, or
156  // 2. a previous call to pthread_mutex_lock failed
157  // both of which are impossible, unless
158  // something bad like memory corruption occurs.
159  _ASSERT(lResult == 0);
160 }
161 
163 //
164 // MSynch::InprocessRecursiveMutex::SmartLock
165 //
168  mrMyMutex(irMutex),
169  mIsLocked(false)
170 {
171  mrMyMutex.Lock();
172  mIsLocked = true;
173 }
174 
176 {
177  if (mIsLocked)
178  {
179  mrMyMutex.Unlock();
180  }
181 }
182 
183 #ifndef WIN32
185  pthread_cond_t& irConditionalVariable) const
186 {
187  const int lResult = ::pthread_cond_wait(&irConditionalVariable, &mrMyMutex.mMutex);
188 
189  if (lResult != 0)
190  {
191 #if !defined(_NO_EXCEPTION)
192  throw ("::pthread_cond_wait failed");
193 #else
194  printf("%s\n","MSynch::InprocessRecursiveMutex::SmartLock::WaitUntilSpuriouslyWokenUp: ::pthread_cond_wait failed");
195  return;
196 #endif
197  }
198 }
199 
201  pthread_cond_t& irConditionalVariable,
202  const struct timespec& irAbsoluteTimeout) const
203 {
204  const int lResult = ::pthread_cond_timedwait(&irConditionalVariable, &mrMyMutex.mMutex, &irAbsoluteTimeout);
205 
206  if (lResult == ETIMEDOUT)
207  {
208  return false;
209  }
210  else if (lResult != 0)
211  {
212 #if !defined(_NO_EXCEPTION)
213  throw ("::pthread_cond_timedwait failed");
214 #else
215  printf("%s\n","MSynch::InprocessRecursiveMutex::SmartLock::WaitUntilSpuriouslyWokenUpOrTimeoutExpired: ::pthread_cond_timedwait failed");
216  return false;
217 #endif
218  }
219 
220  return true;
221 }
222 #endif // WIN32
223 
224 #endif // MSynch_InprocessRecursiveMutex_h
void Unlock()
Definition: InprocessRecursiveMutex.h:149
bool Lock_NoWait()
Definition: InprocessRecursiveMutex.h:121
bool WaitUntilSpuriouslyWokenUpOrTimeoutExpired(pthread_cond_t &irConditionalVariable, const struct timespec &irAbsoluteTimeout) const
Definition: InprocessRecursiveMutex.h:200
#define _ASSERT(x)
Definition: Asserte.h:34
Definition: CriticalSectionImpl.h:20
SmartLock(InprocessRecursiveMutex &irMutex)
Definition: InprocessRecursiveMutex.h:167
void Lock()
Definition: InprocessRecursiveMutex.h:99
friend class BootstrapCriticalSectionImpl
Definition: InprocessRecursiveMutex.h:78
void Unlock()
Definition: InprocessRecursiveMutex.h:45
Definition: InprocessRecursiveMutex.h:25
Definition: ReferenceCountedImpl.h:18
void WaitUntilSpuriouslyWokenUp(pthread_cond_t &irConditionalVariable) const
this method is here only for the ManualEvent
Definition: InprocessRecursiveMutex.h:184
Definition: InprocessRecursiveMutex.h:31
~InprocessRecursiveMutex()
Definition: InprocessRecursiveMutex.h:90
~SmartLock()
Definition: InprocessRecursiveMutex.h:175
void Lock()
Definition: InprocessRecursiveMutex.h:38