MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mutex.cpp
1 /*
2  Copyright (C) 2003-2007 MySQL AB
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 
20 #include "SimulatedBlock.hpp"
21 #include "Mutex.hpp"
22 #include <signaldata/UtilLock.hpp>
23 
24 SimulatedBlock::MutexManager::MutexManager(class SimulatedBlock & block)
25  : m_block(block),
26  m_activeMutexes(m_mutexPool) {
27 }
28 
29 bool
30 SimulatedBlock::MutexManager::setSize(Uint32 maxNoOfActiveMutexes){
31  return m_mutexPool.setSize(maxNoOfActiveMutexes);
32 }
33 
34 Uint32
35 SimulatedBlock::MutexManager::getSize() const {
36  return m_mutexPool.getSize();
37 }
38 
39 bool
40 SimulatedBlock::MutexManager::seize(ActiveMutexPtr& ptr){
41  return m_activeMutexes.seize(ptr);
42 }
43 
44 void
45 SimulatedBlock::MutexManager::release(Uint32 activeMutexPtrI){
46  m_activeMutexes.release(activeMutexPtrI);
47 }
48 
49 void
50 SimulatedBlock::MutexManager::getPtr(ActiveMutexPtr& ptr){
51  m_activeMutexes.getPtr(ptr);
52 }
53 
54 BlockReference
55 SimulatedBlock::MutexManager::reference() const {
56  return m_block.reference();
57 }
58 
59 void
61  int err_code,
62  const char* extra)
63 {
64  m_block.progError(line, err_code, extra);
65 }
66 
67 void
68 SimulatedBlock::MutexManager::create(Signal* signal, ActiveMutexPtr& ptr){
69 
70  UtilCreateLockReq * req = (UtilCreateLockReq*)signal->getDataPtrSend();
71  req->senderData = ptr.i;
72  req->senderRef = m_block.reference();
73  req->lockId = ptr.p->m_mutexId;
74  req->lockType = UtilCreateLockReq::Mutex;
75 
76  m_block.sendSignal(DBUTIL_REF,
77  GSN_UTIL_CREATE_LOCK_REQ,
78  signal,
79  UtilCreateLockReq::SignalLength,
80  JBB);
81 
82  ptr.p->m_gsn = GSN_UTIL_CREATE_LOCK_REQ;
83 }
84 
85 void
86 SimulatedBlock::MutexManager::execUTIL_CREATE_LOCK_REF(Signal* signal){
87 
88  UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtr();
89  ActiveMutexPtr ptr;
90  m_activeMutexes.getPtr(ptr, ref->senderData);
91  ndbrequire(ptr.p->m_gsn == GSN_UTIL_CREATE_LOCK_REQ);
92  ndbrequire(ptr.p->m_mutexId == ref->lockId);
93 
94  ptr.p->m_gsn = 0;
95  m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
96 }
97 
98 void
99 SimulatedBlock::MutexManager::execUTIL_CREATE_LOCK_CONF(Signal* signal){
100 
101  UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtr();
102  ActiveMutexPtr ptr;
103  m_activeMutexes.getPtr(ptr, conf->senderData);
104  ndbrequire(ptr.p->m_gsn == GSN_UTIL_CREATE_LOCK_REQ);
105  ndbrequire(ptr.p->m_mutexId == conf->lockId);
106 
107  ptr.p->m_gsn = 0;
108  m_block.execute(signal, ptr.p->m_callback, 0);
109 }
110 
111 
112 void
113 SimulatedBlock::MutexManager::destroy(Signal* signal, ActiveMutexPtr& ptr){
114 
115  UtilDestroyLockReq * req = (UtilDestroyLockReq*)signal->getDataPtrSend();
116  req->senderData = ptr.i;
117  req->senderRef = m_block.reference();
118  req->lockId = ptr.p->m_mutexId;
119 
120  m_block.sendSignal(DBUTIL_REF,
121  GSN_UTIL_DESTROY_LOCK_REQ,
122  signal,
123  UtilDestroyLockReq::SignalLength,
124  JBB);
125 
126  ptr.p->m_gsn = GSN_UTIL_DESTROY_LOCK_REQ;
127 }
128 
129 void
130 SimulatedBlock::MutexManager::execUTIL_DESTORY_LOCK_REF(Signal* signal){
131  UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtr();
132  ActiveMutexPtr ptr;
133  m_activeMutexes.getPtr(ptr, ref->senderData);
134  ndbrequire(ptr.p->m_gsn == GSN_UTIL_DESTROY_LOCK_REQ);
135  ndbrequire(ptr.p->m_mutexId == ref->lockId);
136 
137  ptr.p->m_gsn = 0;
138  m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
139 }
140 
141 void
142 SimulatedBlock::MutexManager::execUTIL_DESTORY_LOCK_CONF(Signal* signal){
143  UtilDestroyLockConf * conf = (UtilDestroyLockConf*)signal->getDataPtr();
144  ActiveMutexPtr ptr;
145  m_activeMutexes.getPtr(ptr, conf->senderData);
146  ndbrequire(ptr.p->m_gsn == GSN_UTIL_DESTROY_LOCK_REQ);
147  ndbrequire(ptr.p->m_mutexId == conf->lockId);
148 
149  ptr.p->m_gsn = 0;
150  m_block.execute(signal, ptr.p->m_callback, 0);
151 }
152 
153 
154 void
155 SimulatedBlock::MutexManager::lock(Signal* signal,
156  ActiveMutexPtr& ptr,
157  Uint32 flags){
158 
159  UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend();
160  req->senderData = ptr.i;
161  req->senderRef = m_block.reference();
162  req->lockId = ptr.p->m_mutexId;
163  req->requestInfo = flags;
164  req->extra = ptr.p->m_callback.m_callbackData;
165 
166  m_block.sendSignal(DBUTIL_REF,
167  GSN_UTIL_LOCK_REQ,
168  signal,
169  UtilLockReq::SignalLength,
170  JBB);
171 
172  ptr.p->m_gsn = GSN_UTIL_LOCK_REQ;
173 }
174 
175 void
176 SimulatedBlock::MutexManager::execUTIL_LOCK_REF(Signal* signal){
177  UtilLockRef * ref = (UtilLockRef*)signal->getDataPtr();
178  ActiveMutexPtr ptr;
179  m_activeMutexes.getPtr(ptr, ref->senderData);
180  ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ);
181  ndbrequire(ptr.p->m_mutexId == ref->lockId);
182 
183  bool notify = ref->errorCode == UtilLockRef::InLockQueue;
184  CallbackFunction fun = ptr.p->m_callback.m_callbackFunction;
185 
186  if (!notify)
187  {
188  ptr.p->m_gsn = 0;
189  }
190  m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
191 
192  if (notify)
193  {
194  // execute clears function so that same callback shouldnt be called twice
195  ptr.p->m_callback.m_callbackFunction = fun;
196  }
197 }
198 
199 void
200 SimulatedBlock::MutexManager::execUTIL_LOCK_CONF(Signal* signal){
201  UtilLockConf * conf = (UtilLockConf*)signal->getDataPtr();
202  ActiveMutexPtr ptr;
203  m_activeMutexes.getPtr(ptr, conf->senderData);
204  ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ);
205  ndbrequire(ptr.p->m_mutexId == conf->lockId);
206 
207  ptr.p->m_gsn = 0;
208  m_block.execute(signal, ptr.p->m_callback, 0);
209 }
210 
211 void
212 SimulatedBlock::MutexManager::unlock(Signal* signal, ActiveMutexPtr& ptr){
213  UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtrSend();
214  req->senderData = ptr.i;
215  req->senderRef = m_block.reference();
216  req->lockId = ptr.p->m_mutexId;
217 
218  m_block.sendSignal(DBUTIL_REF,
219  GSN_UTIL_UNLOCK_REQ,
220  signal,
221  UtilUnlockReq::SignalLength,
222  JBB);
223 
224  ptr.p->m_gsn = GSN_UTIL_UNLOCK_REQ;
225 }
226 
227 void
228 SimulatedBlock::MutexManager::execUTIL_UNLOCK_REF(Signal* signal){
229  UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtr();
230  ActiveMutexPtr ptr;
231  m_activeMutexes.getPtr(ptr, ref->senderData);
232  ndbrequire(ptr.p->m_gsn == GSN_UTIL_UNLOCK_REQ);
233  ndbrequire(ptr.p->m_mutexId == ref->lockId);
234 
235  ptr.p->m_gsn = 0;
236  m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
237 }
238 
239 void
240 SimulatedBlock::MutexManager::execUTIL_UNLOCK_CONF(Signal* signal){
241  UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtr();
242  ActiveMutexPtr ptr;
243  m_activeMutexes.getPtr(ptr, conf->senderData);
244  ndbrequire(ptr.p->m_gsn == GSN_UTIL_UNLOCK_REQ);
245  ndbrequire(ptr.p->m_mutexId == conf->lockId);
246 
247  ptr.p->m_gsn = 0;
248  m_block.execute(signal, ptr.p->m_callback, 0);
249 }
250 
251 void
252 Mutex::release(SimulatedBlock::MutexManager& mgr,
253  Uint32 activePtrI, Uint32 mutexId){
255  ptr.i = activePtrI;
256  mgr.getPtr(ptr);
257  if(ptr.p->m_gsn == 0 && ptr.p->m_mutexId == mutexId){
258  mgr.release(activePtrI);
259  return;
260  }
261 
262  if(ptr.p->m_mutexId != mutexId)
263  ErrorReporter::handleAssert("MutexHandle::release invalid handle",
264  __FILE__, __LINE__);
265  ErrorReporter::handleAssert("MutexHandle::release of mutex inuse",
266  __FILE__, __LINE__);
267 }
268 
269 void
270 Mutex::unlock(){
271  if(!m_ptr.isNull()){
272  m_mgr.getPtr(m_ptr);
273  if(m_ptr.p->m_mutexId == m_mutexId){
275  { &SimulatedBlock::ignoreMutexUnlockCallback, m_ptr.i };
276  m_ptr.p->m_callback = c;
277  m_mgr.unlock(m_signal, m_ptr);
278  m_ptr.setNull(); // Remove reference
279  }
280  }
281 }
282