diff options
Diffstat (limited to 'storage/ndb/src/kernel/vm/Mutex.cpp')
-rw-r--r-- | storage/ndb/src/kernel/vm/Mutex.cpp | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/vm/Mutex.cpp b/storage/ndb/src/kernel/vm/Mutex.cpp new file mode 100644 index 00000000000..aab9e74312b --- /dev/null +++ b/storage/ndb/src/kernel/vm/Mutex.cpp @@ -0,0 +1,287 @@ +/* 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> + +SimulatedBlock::MutexManager::MutexManager(class SimulatedBlock & block) + : m_block(block), + m_activeMutexes(m_mutexPool) { +} + +bool +SimulatedBlock::MutexManager::setSize(Uint32 maxNoOfActiveMutexes){ + return m_mutexPool.setSize(maxNoOfActiveMutexes); +} + +Uint32 +SimulatedBlock::MutexManager::getSize() const { + return m_mutexPool.getSize(); +} + +bool +SimulatedBlock::MutexManager::seize(ActiveMutexPtr& ptr){ + return m_activeMutexes.seize(ptr); +} + +void +SimulatedBlock::MutexManager::release(Uint32 activeMutexPtrI){ + m_activeMutexes.release(activeMutexPtrI); +} + +void +SimulatedBlock::MutexManager::getPtr(ActiveMutexPtr& ptr){ + m_activeMutexes.getPtr(ptr); +} + +BlockReference +SimulatedBlock::MutexManager::reference() const { + return m_block.reference(); +} + +void +SimulatedBlock::MutexManager::progError(int line, + int err_code, + const char* extra) +{ + m_block.progError(line, err_code, extra); +} + +void +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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 +SimulatedBlock::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(SimulatedBlock::MutexManager& mgr, + Uint32 activePtrI, Uint32 mutexId){ + SimulatedBlock::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){ + SimulatedBlock::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 + } + } +} + |