2
Copyright (C) 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc.
3
All rights reserved. Use is subject to license terms.
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.
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.
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
19
#ifndef BLOCK_MUTEX_HPP
20
#define BLOCK_MUTEX_HPP
22
#include "Callback.hpp"
23
#include "SimulatedBlock.hpp"
24
#include <signaldata/UtilLock.hpp>
29
* MutexHandle - A "reference" to a mutex
30
* - Should be used together with Mutex
35
MutexHandle(Uint32 id);
38
void release(SimulatedBlock::MutexManager & mgr);
41
const Uint32 m_mutexId;
42
Uint32 m_activeMutexPtrI;
46
* MutexHandle2 - A template-based "reference" to a mutex
48
template<Uint32 MutexId>
55
void release(SimulatedBlock::MutexManager & mgr);
57
Uint32 getHandle() const;
58
void setHandle(Uint32 handle);
59
void clear(); // disassociate handle from activemutexptr
62
Uint32 m_activeMutexPtrI;
66
* A mutex - Used together with a MutexHandle to be put on the stack
70
Mutex(Signal*, SimulatedBlock::MutexManager & mgr, MutexHandle &);
72
template<Uint32 MutexId>
73
Mutex(Signal*, SimulatedBlock::MutexManager & mgr, MutexHandle2<MutexId> &);
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
85
bool create(SimulatedBlock::Callback & callback);
86
bool destroy(SimulatedBlock::Callback & callback);
90
SimulatedBlock::MutexManager & m_mgr;
91
const Uint32 m_mutexId;
93
SimulatedBlock::MutexManager::ActiveMutexPtr m_ptr;
96
static void release(SimulatedBlock::MutexManager&,
97
Uint32 activePtrI, Uint32 mutexId);
101
MutexHandle::MutexHandle(Uint32 id) : m_mutexId(id) {
102
m_activeMutexPtrI = RNIL;
107
MutexHandle::isNull() const {
108
return m_activeMutexPtrI == RNIL;
113
MutexHandle::release(SimulatedBlock::MutexManager & mgr){
115
Mutex::release(mgr, m_activeMutexPtrI, m_mutexId);
116
m_activeMutexPtrI = RNIL;
120
template<Uint32 MutexId>
122
MutexHandle2<MutexId>::MutexHandle2() {
123
m_activeMutexPtrI = RNIL;
126
template<Uint32 MutexId>
129
MutexHandle2<MutexId>::isNull() const {
130
return m_activeMutexPtrI == RNIL;
134
template<Uint32 MutexId>
137
MutexHandle2<MutexId>::release(SimulatedBlock::MutexManager & mgr){
139
Mutex::release(mgr, m_activeMutexPtrI, MutexId);
140
m_activeMutexPtrI = RNIL;
144
template<Uint32 MutexId>
147
MutexHandle2<MutexId>::getHandle() const
149
return m_activeMutexPtrI;
152
template<Uint32 MutexId>
155
MutexHandle2<MutexId>::clear()
157
m_activeMutexPtrI = RNIL;
160
template<Uint32 MutexId>
163
MutexHandle2<MutexId>::setHandle(Uint32 val)
165
if (m_activeMutexPtrI == RNIL)
167
m_activeMutexPtrI = val;
170
ErrorReporter::handleAssert("Mutex::setHandle mutex alreay inuse",
175
Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr,
179
m_mutexId(mh.m_mutexId),
180
m_srcPtrI(mh.m_activeMutexPtrI){
186
template<Uint32 MutexId>
188
Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr,
189
MutexHandle2<MutexId> & mh)
193
m_srcPtrI(mh.m_activeMutexPtrI){
208
Mutex::release(m_mgr, m_ptr.i, m_mutexId);
215
Mutex::isNull() const {
216
return m_ptr.isNull();
221
Mutex::lock(SimulatedBlock::Callback & callback, bool exclusive, bool notify){
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));
233
ErrorReporter::handleAssert("Mutex::lock mutex alreay inuse",
240
Mutex::trylock(SimulatedBlock::Callback & callback, bool exclusive){
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));
252
ErrorReporter::handleAssert("Mutex::trylock mutex alreay inuse",
259
Mutex::unlock(SimulatedBlock::Callback & callback){
262
if(m_ptr.p->m_mutexId == m_mutexId){
263
m_ptr.p->m_callback = callback;
264
m_mgr.unlock(m_signal, m_ptr);
268
ErrorReporter::handleAssert("Mutex::unlock invalid mutex",
274
Mutex::create(SimulatedBlock::Callback & callback){
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);
284
ErrorReporter::handleAssert("Mutex::create mutex alreay inuse",
291
Mutex::destroy(SimulatedBlock::Callback & callback){
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);
301
ErrorReporter::handleAssert("Mutex::destroy mutex alreay inuse",