blocxx
RWLocker.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) 2005, Vintela, Inc. All rights reserved.
3 * Copyright (C) 2006, Novell, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of
14 * Vintela, Inc.,
15 * nor Novell, Inc.,
16 * nor the names of its contributors or employees may be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *******************************************************************************/
32 
33 
39 #ifndef BLOCXX_RWLOCKER_HPP_INCLUDE_GUARD_
40 #define BLOCXX_RWLOCKER_HPP_INCLUDE_GUARD_
41 #include "blocxx/BLOCXX_config.h"
43 
44 namespace BLOCXX_NAMESPACE
45 {
46 
49 // The locker is recursive and also supports upgrading a read-lock to a write lock
50 class BLOCXX_COMMON_API RWLocker
51 {
52 public:
53  RWLocker();
54  ~RWLocker();
55 
59  void getReadLock(const Timeout& timeout);
60  void getReadLock(UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED;
61 
68  void getWriteLock(const Timeout& timeout);
69  void getWriteLock(UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED;
70 
74  void releaseReadLock();
75 
79  void releaseWriteLock();
80 
81 private:
82  // Have to do this because on some platforms one thread may have different values for
83  // a Thread_t, and ThreadImpl::sameThreads() has to be called to know if they refer
84  // to the same one.
86  {
87  bool operator()(Thread_t x, Thread_t y) const;
88  };
89 
91 
92  // unimplemented
93  RWLocker(const RWLocker&);
94  RWLocker& operator=(const RWLocker&);
95 };
97 class BLOCXX_COMMON_API ReadLock
98 {
99 public:
100  ReadLock(RWLocker& locker, const Timeout& timeout)
101  : m_locker(&locker)
102  , m_released(false)
103  {
104  m_locker->getReadLock(timeout);
105  }
106  ReadLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED; // in 4.0.0
108  {
109  release();
110  }
111  void lock(const Timeout& timeout)
112  {
113  if (m_released)
114  {
115  m_locker->getReadLock(timeout);
116  m_released = false;
117  }
118  }
119  BLOCXX_DEPRECATED void lock(UInt32 sTimeout, UInt32 usTimeout=0)
120  {
121  if (m_released)
122  {
123  m_locker->getReadLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0));
124  m_released = false;
125  }
126  }
127  void release()
128  {
129  if (!m_released)
130  {
131  m_locker->releaseReadLock();
132  m_released = true;
133  }
134  }
135 private:
138  // noncopyable
139  ReadLock(const ReadLock&);
140  ReadLock& operator=(const ReadLock&);
141 };
142 
143 inline
144 ReadLock::ReadLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout)
145  : m_locker(&locker)
146  , m_released(false)
147 {
148  m_locker->getReadLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0));
149 }
151 class BLOCXX_COMMON_API WriteLock
152 {
153 public:
154  WriteLock(RWLocker& locker, const Timeout& timeout)
155  : m_locker(&locker)
156  , m_released(false)
157  {
158  m_locker->getWriteLock(timeout);
159  }
160  WriteLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED; // in 4.0.0
162  {
163  release();
164  }
165  void lock(const Timeout& timeout)
166  {
167  if (m_released)
168  {
169  m_locker->getWriteLock(timeout);
170  m_released = false;
171  }
172  }
173  BLOCXX_DEPRECATED void lock(UInt32 sTimeout, UInt32 usTimeout=0) // in 4.0.0
174  {
175  if (m_released)
176  {
177  m_locker->getWriteLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0));
178  m_released = false;
179  }
180  }
181  void release()
182  {
183  if (!m_released)
184  {
185  m_locker->releaseWriteLock();
186  m_released = true;
187  }
188  }
189 private:
192 
193  // noncopyable
194  WriteLock(const WriteLock&);
195  WriteLock& operator=(const WriteLock&);
196 };
197 
198 inline
199 WriteLock::WriteLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout)
200  : m_locker(&locker)
201  , m_released(false)
202 {
203  m_locker->getWriteLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0));
204 }
205 
206 } // end namespace BLOCXX_NAMESPACE
207 
208 #endif