MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SafeCounter.cpp
1 /*
2  Copyright (C) 2003, 2005-2008 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 "SafeCounter.hpp"
22 #include <signaldata/NodeFailRep.hpp>
23 
24 SafeCounterManager::SafeCounterManager(class SimulatedBlock & block)
25  : m_block(block),
26  m_activeCounters(m_counterPool)
27 {}
28 
29 bool
30 SafeCounterManager::setSize(Uint32 maxNoOfActiveMutexes, bool exit_on_error) {
31  return m_counterPool.setSize(maxNoOfActiveMutexes, false, exit_on_error);
32 }
33 
34 Uint32
35 SafeCounterManager::getSize() const {
36  return m_counterPool.getSize();
37 }
38 
39 Uint32
40 SafeCounterManager::getNoOfFree() const {
41  return m_counterPool.getNoOfFree();
42 }
43 
44 bool
45 SafeCounterManager::seize(ActiveCounterPtr& ptr){
46  return m_activeCounters.seize(ptr);
47 }
48 
49 void
50 SafeCounterManager::release(ActiveCounterPtr& ptr){
51  m_activeCounters.release(ptr);
52 }
53 
54 void
55 SafeCounterManager::getPtr(ActiveCounterPtr& ptr, Uint32 ptrI){
56  m_activeCounters.getPtr(ptr, ptrI);
57 }
58 
59 
60 void
61 SafeCounterManager::printNODE_FAILREP(){
62  ActiveCounterPtr ptr;
63 
64  NdbNodeBitmask nodes;
65  nodes.clear();
66  // nodes.bitORC(nodes);
67 
68  for(m_activeCounters.first(ptr); !ptr.isNull(); m_activeCounters.next(ptr)){
69  ActiveCounter::SignalDesc desc = ptr.p->m_signalDesc;
70  ndbout_c("theData[desc.m_senderDataOffset=%u] = %u",
71  desc.m_senderDataOffset, ptr.p->m_senderData);
72  ndbout_c("theData[desc.m_errorCodeOffset=%u] = %u",
73  desc.m_errorCodeOffset, desc.m_nodeFailErrorCode);
74  Uint32 len = MAX(MAX(desc.m_senderDataOffset, desc.m_errorCodeOffset),
75  desc.m_senderRefOffset);
76 
77  NdbNodeBitmask overlapping = ptr.p->m_nodes;
78  Uint32 i = 0;
79  while((i = overlapping.find(i)) != NdbNodeBitmask::NotFound){
80  ndbout_c(" theData[desc.m_senderRefOffset=%u] = %x",
81  desc.m_senderRefOffset, numberToRef(desc.m_block, i));
82  ndbout_c(" sendSignal(%x,%u,signal,%u,JBB",
83  m_block.reference(), desc.m_gsn, len+1);
84  i++;
85  }
86  }
87 }
88 
89 void
90 SafeCounterManager::execNODE_FAILREP(Signal* signal){
91  Uint32 * theData = signal->getDataPtrSend();
92  ActiveCounterPtr ptr;
93  NdbNodeBitmask nodes;
94  nodes.assign(NdbNodeBitmask::Size,
95  ((const NodeFailRep*)signal->getDataPtr())->theNodes);
96 
97  for(m_activeCounters.first(ptr); !ptr.isNull(); m_activeCounters.next(ptr)){
98  if(nodes.overlaps(ptr.p->m_nodes)){
99  ActiveCounter::SignalDesc desc = ptr.p->m_signalDesc;
100  theData[desc.m_senderDataOffset] = ptr.p->m_senderData;
101  theData[desc.m_errorCodeOffset] = desc.m_nodeFailErrorCode;
102  Uint32 len = MAX(MAX(desc.m_senderDataOffset, desc.m_errorCodeOffset),
103  desc.m_senderRefOffset);
104 
105  NdbNodeBitmask overlapping = ptr.p->m_nodes;
106  overlapping.bitAND(nodes);
107  Uint32 i = 0;
108  while((i = overlapping.find(i)) != NdbNodeBitmask::NotFound){
109  theData[desc.m_senderRefOffset] = numberToRef(desc.m_block, i);
110  m_block.sendSignal(m_block.reference(), desc.m_gsn, signal, len+1,JBB);
111  i++;
112  }
113  }
114  }
115 }
116 
117 BlockReference
118 SafeCounterManager::reference() const {
119  return m_block.reference();
120 }
121 
122 void
123 SafeCounterManager::progError(int line, int err_code, const char* extra){
124  m_block.progError(line, err_code, extra);
125 }
126 
127 bool
129 {
131  mgr.getPtr(ptr, m_activeCounterPtrI);
132  ptr.p->m_nodes.clear(nodeId);
133 
134  if (ptr.p->m_nodes.isclear()){
135  mgr.release(ptr);
136  m_activeCounterPtrI = RNIL;
137  return true;
138  }
139  return false;
140 }
141 
143  bool clear = m_count == 0;
144  bool isnull = m_ptr.i == RNIL;
145 
146  m_activeCounterPtrI = m_ptr.i;
147 
148  if(clear && isnull)
149  return;
150 
151  if(clear && !isnull){
152  m_mgr.release(m_ptr);
153  m_activeCounterPtrI = RNIL;
154  return;
155  }
156 
160  if(!isnull){
161  m_ptr.p->m_nodes = m_nodes;
162  return;
163  }
164 
165  ErrorReporter::handleAssert("~SafeCounter:: wo/ init", __FILE__, __LINE__);
166 }