AnimatLab  2
Test
StdCriticalSectionInternal.cpp
1 
7 // CStdCriticalSection
9 //
10 // A ::TryEnterCriticalSection type thing that works on 9x
11 //
12 // Written by Olan Patrick Barnes (patrick@mfcfree.com)
13 // Copyright (c) 2001 Olan Patrick Barnes
14 //
15 // This code may be used in compiled form in any way you desire. This
16 // file may be redistributed by any means PROVIDING it is
17 // not sold for profit without the authors written consent, and
18 // providing that this notice and the authors name is included.
19 //
20 // This file is provided "as is" with no expressed or implied warranty.
21 // The author accepts no liability if it causes any damage to you or your
22 // computer whatsoever.
23 //
24 // Description:
25 //
26 // ::TryEnterCriticalSection() is only available on NT platforms, and you
27 // may need to support 9x. This is a custom critical section class that
28 // allows for "try-enter" logic. It operates 100% in user mode (this
29 // class does not use expensive kernel objects), making use of the
30 // ::InterlockedExchange() and ::GetCurrentThreadId() API's.
31 //
33 
34 #include "StdAfx.h"
35 #include "StdCriticalSection.h"
36 #include "StdCriticalSectionInternal.h"
37 
38 namespace StdUtils
39 {
40 
53 #ifdef WIN32
54  CStdCriticalSectionInternal::InternalLocker::InternalLocker(boost::atomic<LockState> &iBusy) :
55  m_iBusy(iBusy)
56  {
57  while (m_iBusy.exchange(Locked, boost::memory_order_acquire) == Locked)
58  {
59  Sleep(0);
60  }
61  }
62 #else
64  m_iBusy(iBusy)
65  {
66  while (m_iBusy.exchange(Locked, std::memory_order_acquire) == Locked)
67  {
68  sleep(0);
69  }
70  }
71 #endif
72 
84 {
85 #ifdef WIN32
86  m_iBusy.exchange(Unlocked, boost::memory_order_acquire);
87 #else
88  m_iBusy.exchange(Unlocked, std::memory_order_acquire);
89 #endif
90 }
91 
99  m_iBusy(Unlocked),
100  m_bOwned(false),
101  m_ulRefCnt(0)
102 {
103 }
104 
115 {
116  Leave(); //lint !e534
117 }
118 
119 //TryEnter
120 
121 
136 {
137  bool bRet(false);
138  InternalLocker locker(m_iBusy);
139 
140  if (!m_bOwned)
141  {
142  //Nobody owns this cs, so the current will gain ownership
143  //ATLASSERT(m_ulRefCnt == 0);
144  m_dwOwner = boost::this_thread::get_id();
145  m_bOwned = true;
146  m_ulRefCnt = 1;
147  bRet = true;
148  }
149  else if (m_dwOwner == boost::this_thread::get_id())
150  {
151  //The current thread already owns this cs
152  //ATLASSERT(m_ulRefCnt > 0);
153  m_ulRefCnt++;
154  bRet = true;
155  }
156 
157  //If we return false, some other thread already owns this cs, so
158  // we will not increment the recursive ownership count (m_ulRefCnt)
159  return bRet;
160 }
161 
172 bool CStdCriticalSectionInternal::Enter(long lMilliTimeout)
173 {
174  bool bDone = false;
175  long lTotal = 0;
176 
177  while(!bDone)
178  {
179  bDone = TryEnter();
180 
181  if(!bDone)
182  {
183  #ifdef WIN32
184  Sleep(10);
185  #else
186  sleep(10);
187  #endif
188  lTotal+=10;
189 
190  if(lMilliTimeout > 0 && lTotal >= lMilliTimeout)
191  return false;
192  }
193  }
194 
195  return true;
196 }
197 
198 
214 {
215  InternalLocker locker(m_iBusy);
216  //If the current thread owns this cs
217  if (m_dwOwner == boost::this_thread::get_id())
218  {
219  //and if decrementing the recursive ownership count results in
220  // a recursive ownership count of zero, then the current thread
221  // should no longer own this cs
222  //ATLASSERT(m_ulRefCnt > 0);
223  if (--m_ulRefCnt == 0)
224  {
225  //By setting m_dwOwner to zero, we're stating that no thread owns
226  // this cs
227  m_bOwned = false;
228  }
229  return true;
230  }
231  return false;
232 }
233 
234 } //StdUtils
235 
ULONG m_ulRefCnt
The number of reference counts to this critical section.
Declares the standard critical section class.
std::atomic< int > & m_iBusy
Tells if this is busy.
bool Leave()
Leaves this critical section.
std::atomic< int > m_iBusy
Tells if this critical section is currently being used.
Namespace for the standard utility objects.
Definition: MarkupSTL.cpp:19
bool Enter(long lMilliTimeout=-1)
Try's to enter the critical section. Waits until it can get in, or until timeout. ...