1 /* Copyright (c) 2003-2005 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 #include "SimulatedBlock.hpp"
19 #include <signaldata/UtilLock.hpp>
21 SimulatedBlock::MutexManager::MutexManager(class SimulatedBlock
& block
)
23 m_activeMutexes(m_mutexPool
) {
27 SimulatedBlock::MutexManager::setSize(Uint32 maxNoOfActiveMutexes
){
28 return m_mutexPool
.setSize(maxNoOfActiveMutexes
);
32 SimulatedBlock::MutexManager::getSize() const {
33 return m_mutexPool
.getSize();
37 SimulatedBlock::MutexManager::seize(ActiveMutexPtr
& ptr
){
38 return m_activeMutexes
.seize(ptr
);
42 SimulatedBlock::MutexManager::release(Uint32 activeMutexPtrI
){
43 m_activeMutexes
.release(activeMutexPtrI
);
47 SimulatedBlock::MutexManager::getPtr(ActiveMutexPtr
& ptr
){
48 m_activeMutexes
.getPtr(ptr
);
52 SimulatedBlock::MutexManager::reference() const {
53 return m_block
.reference();
57 SimulatedBlock::MutexManager::progError(int line
,
61 m_block
.progError(line
, err_code
, extra
);
65 SimulatedBlock::MutexManager::create(Signal
* signal
, ActiveMutexPtr
& ptr
){
67 UtilCreateLockReq
* req
= (UtilCreateLockReq
*)signal
->getDataPtrSend();
68 req
->senderData
= ptr
.i
;
69 req
->senderRef
= m_block
.reference();
70 req
->lockId
= ptr
.p
->m_mutexId
;
71 req
->lockType
= UtilCreateLockReq::Mutex
;
73 m_block
.sendSignal(DBUTIL_REF
,
74 GSN_UTIL_CREATE_LOCK_REQ
,
76 UtilCreateLockReq::SignalLength
,
79 ptr
.p
->m_gsn
= GSN_UTIL_CREATE_LOCK_REQ
;
83 SimulatedBlock::MutexManager::execUTIL_CREATE_LOCK_REF(Signal
* signal
){
85 UtilCreateLockRef
* ref
= (UtilCreateLockRef
*)signal
->getDataPtr();
87 m_activeMutexes
.getPtr(ptr
, ref
->senderData
);
88 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_CREATE_LOCK_REQ
);
89 ndbrequire(ptr
.p
->m_mutexId
== ref
->lockId
);
92 m_block
.execute(signal
, ptr
.p
->m_callback
, ref
->errorCode
);
96 SimulatedBlock::MutexManager::execUTIL_CREATE_LOCK_CONF(Signal
* signal
){
98 UtilCreateLockConf
* conf
= (UtilCreateLockConf
*)signal
->getDataPtr();
100 m_activeMutexes
.getPtr(ptr
, conf
->senderData
);
101 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_CREATE_LOCK_REQ
);
102 ndbrequire(ptr
.p
->m_mutexId
== conf
->lockId
);
105 m_block
.execute(signal
, ptr
.p
->m_callback
, 0);
110 SimulatedBlock::MutexManager::destroy(Signal
* signal
, ActiveMutexPtr
& ptr
){
112 UtilDestroyLockReq
* req
= (UtilDestroyLockReq
*)signal
->getDataPtrSend();
113 req
->senderData
= ptr
.i
;
114 req
->senderRef
= m_block
.reference();
115 req
->lockId
= ptr
.p
->m_mutexId
;
116 req
->lockKey
= ptr
.p
->m_mutexKey
;
118 m_block
.sendSignal(DBUTIL_REF
,
119 GSN_UTIL_DESTROY_LOCK_REQ
,
121 UtilDestroyLockReq::SignalLength
,
124 ptr
.p
->m_gsn
= GSN_UTIL_DESTROY_LOCK_REQ
;
128 SimulatedBlock::MutexManager::execUTIL_DESTORY_LOCK_REF(Signal
* signal
){
129 UtilDestroyLockRef
* ref
= (UtilDestroyLockRef
*)signal
->getDataPtr();
131 m_activeMutexes
.getPtr(ptr
, ref
->senderData
);
132 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_DESTROY_LOCK_REQ
);
133 ndbrequire(ptr
.p
->m_mutexId
== ref
->lockId
);
136 m_block
.execute(signal
, ptr
.p
->m_callback
, ref
->errorCode
);
140 SimulatedBlock::MutexManager::execUTIL_DESTORY_LOCK_CONF(Signal
* signal
){
141 UtilDestroyLockConf
* conf
= (UtilDestroyLockConf
*)signal
->getDataPtr();
143 m_activeMutexes
.getPtr(ptr
, conf
->senderData
);
144 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_DESTROY_LOCK_REQ
);
145 ndbrequire(ptr
.p
->m_mutexId
== conf
->lockId
);
148 m_block
.execute(signal
, ptr
.p
->m_callback
, 0);
153 SimulatedBlock::MutexManager::lock(Signal
* signal
, ActiveMutexPtr
& ptr
){
155 UtilLockReq
* req
= (UtilLockReq
*)signal
->getDataPtrSend();
156 req
->senderData
= ptr
.i
;
157 req
->senderRef
= m_block
.reference();
158 req
->lockId
= ptr
.p
->m_mutexId
;
159 req
->requestInfo
= 0;
161 m_block
.sendSignal(DBUTIL_REF
,
164 UtilLockReq::SignalLength
,
167 ptr
.p
->m_gsn
= GSN_UTIL_LOCK_REQ
;
171 SimulatedBlock::MutexManager::trylock(Signal
* signal
, ActiveMutexPtr
& ptr
){
173 UtilLockReq
* req
= (UtilLockReq
*)signal
->getDataPtrSend();
174 req
->senderData
= ptr
.i
;
175 req
->senderRef
= m_block
.reference();
176 req
->lockId
= ptr
.p
->m_mutexId
;
177 req
->requestInfo
= UtilLockReq::TryLock
;
179 m_block
.sendSignal(DBUTIL_REF
,
182 UtilLockReq::SignalLength
,
185 ptr
.p
->m_gsn
= GSN_UTIL_LOCK_REQ
;
189 SimulatedBlock::MutexManager::execUTIL_LOCK_REF(Signal
* signal
){
190 UtilLockRef
* ref
= (UtilLockRef
*)signal
->getDataPtr();
192 m_activeMutexes
.getPtr(ptr
, ref
->senderData
);
193 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_LOCK_REQ
);
194 ndbrequire(ptr
.p
->m_mutexId
== ref
->lockId
);
197 m_block
.execute(signal
, ptr
.p
->m_callback
, ref
->errorCode
);
201 SimulatedBlock::MutexManager::execUTIL_LOCK_CONF(Signal
* signal
){
202 UtilLockConf
* conf
= (UtilLockConf
*)signal
->getDataPtr();
204 m_activeMutexes
.getPtr(ptr
, conf
->senderData
);
205 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_LOCK_REQ
);
206 ndbrequire(ptr
.p
->m_mutexId
== conf
->lockId
);
208 ptr
.p
->m_mutexKey
= conf
->lockKey
;
211 m_block
.execute(signal
, ptr
.p
->m_callback
, 0);
215 SimulatedBlock::MutexManager::unlock(Signal
* signal
, ActiveMutexPtr
& ptr
){
216 UtilUnlockReq
* req
= (UtilUnlockReq
*)signal
->getDataPtrSend();
217 req
->senderData
= ptr
.i
;
218 req
->senderRef
= m_block
.reference();
219 req
->lockId
= ptr
.p
->m_mutexId
;
220 req
->lockKey
= ptr
.p
->m_mutexKey
;
222 m_block
.sendSignal(DBUTIL_REF
,
225 UtilUnlockReq::SignalLength
,
228 ptr
.p
->m_gsn
= GSN_UTIL_UNLOCK_REQ
;
232 SimulatedBlock::MutexManager::execUTIL_UNLOCK_REF(Signal
* signal
){
233 UtilUnlockRef
* ref
= (UtilUnlockRef
*)signal
->getDataPtr();
235 m_activeMutexes
.getPtr(ptr
, ref
->senderData
);
236 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_UNLOCK_REQ
);
237 ndbrequire(ptr
.p
->m_mutexId
== ref
->lockId
);
240 m_block
.execute(signal
, ptr
.p
->m_callback
, ref
->errorCode
);
244 SimulatedBlock::MutexManager::execUTIL_UNLOCK_CONF(Signal
* signal
){
245 UtilUnlockConf
* conf
= (UtilUnlockConf
*)signal
->getDataPtr();
247 m_activeMutexes
.getPtr(ptr
, conf
->senderData
);
248 ndbrequire(ptr
.p
->m_gsn
== GSN_UTIL_UNLOCK_REQ
);
249 ndbrequire(ptr
.p
->m_mutexId
== conf
->lockId
);
252 m_block
.execute(signal
, ptr
.p
->m_callback
, 0);
256 Mutex::release(SimulatedBlock::MutexManager
& mgr
,
257 Uint32 activePtrI
, Uint32 mutexId
){
258 SimulatedBlock::MutexManager::ActiveMutexPtr ptr
;
261 if(ptr
.p
->m_gsn
== 0 && ptr
.p
->m_mutexId
== mutexId
){
262 mgr
.release(activePtrI
);
266 if(ptr
.p
->m_mutexId
!= mutexId
)
267 ErrorReporter::handleAssert("MutexHandle::release invalid handle",
269 ErrorReporter::handleAssert("MutexHandle::release of mutex inuse",
277 if(m_ptr
.p
->m_mutexId
== m_mutexId
){
278 SimulatedBlock::Callback c
=
279 { &SimulatedBlock::ignoreMutexUnlockCallback
, m_ptr
.i
};
280 m_ptr
.p
->m_callback
= c
;
281 m_mgr
.unlock(m_signal
, m_ptr
);
282 m_ptr
.setNull(); // Remove reference