MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mutex.hpp
1 /*
2  Copyright (C) 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef BLOCK_MUTEX_HPP
20 #define BLOCK_MUTEX_HPP
21 
22 #include "Callback.hpp"
23 #include "SimulatedBlock.hpp"
24 #include <signaldata/UtilLock.hpp>
25 
26 class Mutex;
27 
32 class MutexHandle {
33  friend class Mutex;
34 public:
35  MutexHandle(Uint32 id);
36 
37  bool isNull() const;
38  void release(SimulatedBlock::MutexManager & mgr);
39 
40 private:
41  const Uint32 m_mutexId;
42  Uint32 m_activeMutexPtrI;
43 };
44 
48 template<Uint32 MutexId>
49 class MutexHandle2 {
50  friend class Mutex;
51 public:
52  MutexHandle2();
53 
54  bool isNull() const;
55  void release(SimulatedBlock::MutexManager & mgr);
56 
57  Uint32 getHandle() const;
58  void setHandle(Uint32 handle);
59  void clear(); // disassociate handle from activemutexptr
60 
61 private:
62  Uint32 m_activeMutexPtrI;
63 };
64 
68 class Mutex {
69 public:
71 
72  template<Uint32 MutexId>
74 
75  ~Mutex();
76 
77  void release();
78  bool isNull() const ;
79 
80  bool lock(SimulatedBlock::Callback & callback, bool exclusive = true, bool notify = false);
81  bool trylock(SimulatedBlock::Callback & callback, bool exclusive = true);
82  void unlock(SimulatedBlock::Callback & callback);
83  void unlock(); // Ignore callback
84 
85  bool create(SimulatedBlock::Callback & callback);
86  bool destroy(SimulatedBlock::Callback & callback);
87 
88 private:
89  Signal* m_signal;
91  const Uint32 m_mutexId;
92  Uint32 & m_srcPtrI;
94 
95 public:
96  static void release(SimulatedBlock::MutexManager&,
97  Uint32 activePtrI, Uint32 mutexId);
98 };
99 
100 inline
101 MutexHandle::MutexHandle(Uint32 id) : m_mutexId(id) {
102  m_activeMutexPtrI = RNIL;
103 }
104 
105 inline
106 bool
107 MutexHandle::isNull() const {
108  return m_activeMutexPtrI == RNIL;
109 }
110 
111 inline
112 void
113 MutexHandle::release(SimulatedBlock::MutexManager & mgr){
114  if(!isNull()){
115  Mutex::release(mgr, m_activeMutexPtrI, m_mutexId);
116  m_activeMutexPtrI = RNIL;
117  }
118 }
119 
120 template<Uint32 MutexId>
121 inline
123  m_activeMutexPtrI = RNIL;
124 }
125 
126 template<Uint32 MutexId>
127 inline
128 bool
130  return m_activeMutexPtrI == RNIL;
131 }
132 
133 
134 template<Uint32 MutexId>
135 inline
136 void
138  if(!isNull()){
139  Mutex::release(mgr, m_activeMutexPtrI, MutexId);
140  m_activeMutexPtrI = RNIL;
141  }
142 }
143 
144 template<Uint32 MutexId>
145 inline
146 Uint32
148 {
149  return m_activeMutexPtrI;
150 }
151 
152 template<Uint32 MutexId>
153 inline
154 void
156 {
157  m_activeMutexPtrI = RNIL;
158 }
159 
160 template<Uint32 MutexId>
161 inline
162 void
164 {
165  if (m_activeMutexPtrI == RNIL)
166  {
167  m_activeMutexPtrI = val;
168  return;
169  }
170  ErrorReporter::handleAssert("Mutex::setHandle mutex alreay inuse",
171  __FILE__, __LINE__);
172 }
173 
174 inline
175 Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr,
176  MutexHandle & mh)
177  : m_signal(signal),
178  m_mgr(mgr),
179  m_mutexId(mh.m_mutexId),
180  m_srcPtrI(mh.m_activeMutexPtrI){
181 
182  m_ptr.i = m_srcPtrI;
183 
184 }
185 
186 template<Uint32 MutexId>
187 inline
188 Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr,
190  : m_signal(signal),
191  m_mgr(mgr),
192  m_mutexId(MutexId),
193  m_srcPtrI(mh.m_activeMutexPtrI){
194 
195  m_ptr.i = m_srcPtrI;
196 
197 }
198 
199 inline
200 Mutex::~Mutex(){
201  m_srcPtrI = m_ptr.i;
202 }
203 
204 inline
205 void
206 Mutex::release(){
207  if(!m_ptr.isNull()){
208  Mutex::release(m_mgr, m_ptr.i, m_mutexId);
209  m_ptr.setNull();
210  }
211 }
212 
213 inline
214 bool
215 Mutex::isNull() const {
216  return m_ptr.isNull();
217 }
218 
219 inline
220 bool
221 Mutex::lock(SimulatedBlock::Callback & callback, bool exclusive, bool notify){
222  if(m_ptr.isNull()){
223  if(m_mgr.seize(m_ptr)){
224  m_ptr.p->m_mutexId = m_mutexId;
225  m_ptr.p->m_callback = callback;
226  m_mgr.lock(m_signal, m_ptr,
227  ((exclusive == false) ? UtilLockReq::SharedLock : 0) |
228  ((notify == true) ? UtilLockReq::Notify : 0));
229  return true;
230  }
231  return false;
232  }
233  ErrorReporter::handleAssert("Mutex::lock mutex alreay inuse",
234  __FILE__, __LINE__);
235  return false;
236 }
237 
238 inline
239 bool
240 Mutex::trylock(SimulatedBlock::Callback & callback, bool exclusive){
241  if(m_ptr.isNull()){
242  if(m_mgr.seize(m_ptr)){
243  m_ptr.p->m_mutexId = m_mutexId;
244  m_ptr.p->m_callback = callback;
245  m_mgr.lock(m_signal, m_ptr,
246  UtilLockReq::TryLock |
247  ((exclusive == false) ? UtilLockReq::SharedLock : 0));
248  return true;
249  }
250  return false;
251  }
252  ErrorReporter::handleAssert("Mutex::trylock mutex alreay inuse",
253  __FILE__, __LINE__);
254  return false;
255 }
256 
257 inline
258 void
259 Mutex::unlock(SimulatedBlock::Callback & callback){
260  if(!m_ptr.isNull()){
261  m_mgr.getPtr(m_ptr);
262  if(m_ptr.p->m_mutexId == m_mutexId){
263  m_ptr.p->m_callback = callback;
264  m_mgr.unlock(m_signal, m_ptr);
265  return;
266  }
267  }
268  ErrorReporter::handleAssert("Mutex::unlock invalid mutex",
269  __FILE__, __LINE__);
270 }
271 
272 inline
273 bool
274 Mutex::create(SimulatedBlock::Callback & callback){
275  if(m_ptr.isNull()){
276  if(m_mgr.seize(m_ptr)){
277  m_ptr.p->m_mutexId = m_mutexId;
278  m_ptr.p->m_callback = callback;
279  m_mgr.create(m_signal, m_ptr);
280  return true;
281  }
282  return false;
283  }
284  ErrorReporter::handleAssert("Mutex::create mutex alreay inuse",
285  __FILE__, __LINE__);
286  return false;
287 }
288 
289 inline
290 bool
291 Mutex::destroy(SimulatedBlock::Callback & callback){
292  if(m_ptr.isNull()){
293  if(m_mgr.seize(m_ptr)){
294  m_ptr.p->m_mutexId = m_mutexId;
295  m_ptr.p->m_callback = callback;
296  m_mgr.destroy(m_signal, m_ptr);
297  return true;
298  }
299  return false;
300  }
301  ErrorReporter::handleAssert("Mutex::destroy mutex alreay inuse",
302  __FILE__, __LINE__);
303  return false;
304 }
305 
306 
307 #endif