diff options
Diffstat (limited to 'ndb/src/kernel/vm/Mutex.cpp')
-rw-r--r-- | ndb/src/kernel/vm/Mutex.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/ndb/src/kernel/vm/Mutex.cpp b/ndb/src/kernel/vm/Mutex.cpp new file mode 100644 index 00000000000..1dbc6e7ec4a --- /dev/null +++ b/ndb/src/kernel/vm/Mutex.cpp @@ -0,0 +1,282 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#include "SimulatedBlock.hpp" +#include "Mutex.hpp" +#include <signaldata/UtilLock.hpp> + +MutexManager::MutexManager(class SimulatedBlock & block) + : m_block(block), + m_activeMutexes(m_mutexPool) { +} + +bool +MutexManager::setSize(Uint32 maxNoOfActiveMutexes){ + return m_mutexPool.setSize(maxNoOfActiveMutexes); +} + +Uint32 +MutexManager::getSize() const { + return m_mutexPool.getSize(); +} + +bool +MutexManager::seize(ActiveMutexPtr& ptr){ + return m_activeMutexes.seize(ptr); +} + +void +MutexManager::release(Uint32 activeMutexPtrI){ + m_activeMutexes.release(activeMutexPtrI); +} + +void +MutexManager::getPtr(ActiveMutexPtr& ptr){ + m_activeMutexes.getPtr(ptr); +} + +BlockReference +MutexManager::reference() const { + return m_block.reference(); +} + +void +MutexManager::progError(int line, int err_code, const char* extra) { + m_block.progError(line, err_code, extra); +} + +void +MutexManager::create(Signal* signal, ActiveMutexPtr& ptr){ + + UtilCreateLockReq * req = (UtilCreateLockReq*)signal->getDataPtrSend(); + req->senderData = ptr.i; + req->senderRef = m_block.reference(); + req->lockId = ptr.p->m_mutexId; + req->lockType = UtilCreateLockReq::Mutex; + + m_block.sendSignal(DBUTIL_REF, + GSN_UTIL_CREATE_LOCK_REQ, + signal, + UtilCreateLockReq::SignalLength, + JBB); + + ptr.p->m_gsn = GSN_UTIL_CREATE_LOCK_REQ; +} + +void +MutexManager::execUTIL_CREATE_LOCK_REF(Signal* signal){ + + UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, ref->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_CREATE_LOCK_REQ); + ndbrequire(ptr.p->m_mutexId == ref->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, ref->errorCode); +} + +void +MutexManager::execUTIL_CREATE_LOCK_CONF(Signal* signal){ + + UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, conf->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_CREATE_LOCK_REQ); + ndbrequire(ptr.p->m_mutexId == conf->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, 0); +} + + +void +MutexManager::destroy(Signal* signal, ActiveMutexPtr& ptr){ + + UtilDestroyLockReq * req = (UtilDestroyLockReq*)signal->getDataPtrSend(); + req->senderData = ptr.i; + req->senderRef = m_block.reference(); + req->lockId = ptr.p->m_mutexId; + req->lockKey = ptr.p->m_mutexKey; + + m_block.sendSignal(DBUTIL_REF, + GSN_UTIL_DESTROY_LOCK_REQ, + signal, + UtilDestroyLockReq::SignalLength, + JBB); + + ptr.p->m_gsn = GSN_UTIL_DESTROY_LOCK_REQ; +} + +void +MutexManager::execUTIL_DESTORY_LOCK_REF(Signal* signal){ + UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, ref->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_DESTROY_LOCK_REQ); + ndbrequire(ptr.p->m_mutexId == ref->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, ref->errorCode); +} + +void +MutexManager::execUTIL_DESTORY_LOCK_CONF(Signal* signal){ + UtilDestroyLockConf * conf = (UtilDestroyLockConf*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, conf->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_DESTROY_LOCK_REQ); + ndbrequire(ptr.p->m_mutexId == conf->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, 0); +} + + +void +MutexManager::lock(Signal* signal, ActiveMutexPtr& ptr){ + + UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend(); + req->senderData = ptr.i; + req->senderRef = m_block.reference(); + req->lockId = ptr.p->m_mutexId; + req->requestInfo = 0; + + m_block.sendSignal(DBUTIL_REF, + GSN_UTIL_LOCK_REQ, + signal, + UtilLockReq::SignalLength, + JBB); + + ptr.p->m_gsn = GSN_UTIL_LOCK_REQ; +} + +void +MutexManager::trylock(Signal* signal, ActiveMutexPtr& ptr){ + + UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend(); + req->senderData = ptr.i; + req->senderRef = m_block.reference(); + req->lockId = ptr.p->m_mutexId; + req->requestInfo = UtilLockReq::TryLock; + + m_block.sendSignal(DBUTIL_REF, + GSN_UTIL_LOCK_REQ, + signal, + UtilLockReq::SignalLength, + JBB); + + ptr.p->m_gsn = GSN_UTIL_LOCK_REQ; +} + +void +MutexManager::execUTIL_LOCK_REF(Signal* signal){ + UtilLockRef * ref = (UtilLockRef*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, ref->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ); + ndbrequire(ptr.p->m_mutexId == ref->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, ref->errorCode); +} + +void +MutexManager::execUTIL_LOCK_CONF(Signal* signal){ + UtilLockConf * conf = (UtilLockConf*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, conf->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ); + ndbrequire(ptr.p->m_mutexId == conf->lockId); + + ptr.p->m_mutexKey = conf->lockKey; + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, 0); +} + +void +MutexManager::unlock(Signal* signal, ActiveMutexPtr& ptr){ + UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtrSend(); + req->senderData = ptr.i; + req->senderRef = m_block.reference(); + req->lockId = ptr.p->m_mutexId; + req->lockKey = ptr.p->m_mutexKey; + + m_block.sendSignal(DBUTIL_REF, + GSN_UTIL_UNLOCK_REQ, + signal, + UtilUnlockReq::SignalLength, + JBB); + + ptr.p->m_gsn = GSN_UTIL_UNLOCK_REQ; +} + +void +MutexManager::execUTIL_UNLOCK_REF(Signal* signal){ + UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, ref->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_UNLOCK_REQ); + ndbrequire(ptr.p->m_mutexId == ref->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, ref->errorCode); +} + +void +MutexManager::execUTIL_UNLOCK_CONF(Signal* signal){ + UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtr(); + ActiveMutexPtr ptr; + m_activeMutexes.getPtr(ptr, conf->senderData); + ndbrequire(ptr.p->m_gsn == GSN_UTIL_UNLOCK_REQ); + ndbrequire(ptr.p->m_mutexId == conf->lockId); + + ptr.p->m_gsn = 0; + m_block.execute(signal, ptr.p->m_callback, 0); +} + +void +Mutex::release(MutexManager& mgr, Uint32 activePtrI, Uint32 mutexId){ + MutexManager::ActiveMutexPtr ptr; + ptr.i = activePtrI; + mgr.getPtr(ptr); + if(ptr.p->m_gsn == 0 && ptr.p->m_mutexId == mutexId){ + mgr.release(activePtrI); + return; + } + + if(ptr.p->m_mutexId != mutexId) + ErrorReporter::handleAssert("MutexHandle::release invalid handle", + __FILE__, __LINE__); + ErrorReporter::handleAssert("MutexHandle::release of mutex inuse", + __FILE__, __LINE__); +} + +void +Mutex::unlock(){ + if(!m_ptr.isNull()){ + m_mgr.getPtr(m_ptr); + if(m_ptr.p->m_mutexId == m_mutexId){ + Callback c = { &SimulatedBlock::ignoreMutexUnlockCallback, m_ptr.i }; + m_ptr.p->m_callback = c; + m_mgr.unlock(m_signal, m_ptr); + m_ptr.setNull(); // Remove reference + } + } +} + |