MongoDB  2.7.0
rwlockimpl.h
1 // @file rwlockimpl.h
2 
31 #pragma once
32 
33 #include "mutex.h"
34 
35 #if defined(NTDDI_VERSION) && defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
36 
37 // Windows slimreaderwriter version. Newer windows versions only. Under contention this is slower
38 // than boost::shared_mutex, but see https://jira.mongodb.org/browse/SERVER-2327 for why it cannot
39 // be used.
40 
41 namespace mongo {
42  unsigned long long curTimeMicros64();
43 
44  class RWLockBase : boost::noncopyable {
45  friend class SimpleRWLock;
46  SRWLOCK _lock;
47  protected:
48  RWLockBase() { InitializeSRWLock(&_lock); }
49  ~RWLockBase() {
50  // no special action needed to destroy a SRWLOCK
51  }
52  void lock() { AcquireSRWLockExclusive(&_lock); }
53  void unlock() { ReleaseSRWLockExclusive(&_lock); }
54  void lock_shared() { AcquireSRWLockShared(&_lock); }
55  void unlock_shared() { ReleaseSRWLockShared(&_lock); }
56  bool lock_shared_try( int millis ) {
57  if( TryAcquireSRWLockShared(&_lock) )
58  return true;
59  if( millis == 0 )
60  return false;
61  unsigned long long end = curTimeMicros64() + millis*1000;
62  while( 1 ) {
63  Sleep(1);
64  if( TryAcquireSRWLockShared(&_lock) )
65  return true;
66  if( curTimeMicros64() >= end )
67  break;
68  }
69  return false;
70  }
71  bool lock_try( int millis = 0 ) {
72  if( TryAcquireSRWLockExclusive(&_lock) ) // quick check to optimistically avoid calling curTimeMicros64
73  return true;
74  if( millis == 0 )
75  return false;
76  unsigned long long end = curTimeMicros64() + millis*1000;
77  do {
78  Sleep(1);
79  if( TryAcquireSRWLockExclusive(&_lock) )
80  return true;
81  } while( curTimeMicros64() < end );
82  return false;
83  }
84  // no upgradable for this impl
85  void lockAsUpgradable() { lock(); }
86  void unlockFromUpgradable() { unlock(); }
87  void upgrade() { }
88  public:
89  const char * implType() const { return "WINSRW"; }
90  };
91 }
92 
93 #else
94 
95 # if defined(_WIN32)
96 # include "shared_mutex_win.hpp"
97 namespace mongo { typedef boost::modified_shared_mutex shared_mutex; }
98 # else
99 # include <boost/thread/shared_mutex.hpp>
100 namespace mongo { using boost::shared_mutex; }
101 # endif
102 
103 namespace mongo {
104  class RWLockBase : boost::noncopyable {
105  friend class SimpleRWLock;
106  shared_mutex _m;
107  protected:
108  void lock() {
109  _m.lock();
110  }
111  void unlock() {
112  _m.unlock();
113  }
114  void lockAsUpgradable() {
115  _m.lock_upgrade();
116  }
117  void unlockFromUpgradable() { // upgradable -> unlocked
118  _m.unlock_upgrade();
119  }
120  void upgrade() { // upgradable -> exclusive lock
121  _m.unlock_upgrade_and_lock();
122  }
123  void lock_shared() {
124  _m.lock_shared();
125  }
126  void unlock_shared() {
127  _m.unlock_shared();
128  }
129  bool lock_shared_try( int millis ) {
130  return _m.timed_lock_shared( boost::posix_time::milliseconds(millis) );
131  }
132  bool lock_try( int millis = 0 ) {
133  return _m.timed_lock( boost::posix_time::milliseconds(millis) );
134  }
135  public:
136  const char * implType() const { return "boost"; }
137  };
138 }
139 
140 #endif
Definition: shared_mutex_win.hpp:48
separated out as later the implementation of this may be different than RWLock, depending on OS...
Definition: simplerwlock.h:39
Definition: rwlockimpl.h:104