MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SignalSender.cpp
1 /*
2  Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "SignalSender.hpp"
19 #include <kernel/GlobalSignalNumbers.h>
20 #include <NdbSleep.h>
21 #include <SignalLoggerManager.hpp>
22 #include <signaldata/NFCompleteRep.hpp>
23 #include <signaldata/NodeFailRep.hpp>
24 #include <signaldata/TestOrd.hpp>
25 
26 
27 SimpleSignal::SimpleSignal(bool dealloc)
28  : header((BlockReference)0)
29 {
30  memset(ptr, 0, sizeof(ptr));
31  deallocSections = dealloc;
32 }
33 
34 SimpleSignal::SimpleSignal(const SimpleSignal& src)
35  : header(src.header)
36 {
37  deallocSections = true;
38 
39  for (Uint32 i = 0; i<NDB_ARRAY_SIZE(ptr); i++)
40  {
41  ptr[i].p = 0;
42  if (src.ptr[i].p != 0)
43  {
44  ptr[i].p = new Uint32[src.ptr[i].sz];
45  ptr[i].sz = src.ptr[i].sz;
46  memcpy(ptr[i].p, src.ptr[i].p, 4 * src.ptr[i].sz);
47  }
48  }
49 }
50 
51 
53 SimpleSignal::operator=(const SimpleSignal& src)
54 {
55  deallocSections = true;
56  header = src.header;
57  for (Uint32 i = 0; i<NDB_ARRAY_SIZE(ptr); i++)
58  {
59  ptr[i].p = 0;
60  if (src.ptr[i].p != 0)
61  {
62  ptr[i].p = new Uint32[src.ptr[i].sz];
63  ptr[i].sz = src.ptr[i].sz;
64  memcpy(ptr[i].p, src.ptr[i].p, 4 * src.ptr[i].sz);
65  }
66  }
67  return * this;
68 }
69 
70 SimpleSignal::~SimpleSignal(){
71  if(!deallocSections)
72  return;
73 
74  for (Uint32 i = 0; i<NDB_ARRAY_SIZE(ptr); i++)
75  {
76  if (ptr[i].p != 0)
77  {
78  delete [] ptr[i].p;
79  }
80  }
81 }
82 
83 void
84 SimpleSignal::set(class SignalSender& ss,
85  Uint8 trace, Uint16 recBlock, Uint16 gsn, Uint32 len)
86 {
87  header.set(trace, recBlock, gsn, len);
88  header.theSendersBlockRef = refToBlock(ss.getOwnRef());
89 }
90 
91 void
92 SimpleSignal::print(FILE * out) const {
93  fprintf(out, "---- Signal ----------------\n");
94  SignalLoggerManager::printSignalHeader(out, header, 0, 0, false);
95  SignalLoggerManager::printSignalData(out, header, getDataPtr());
96  for(Uint32 i = 0; i<header.m_noOfSections; i++){
97  Uint32 len = ptr[i].sz;
98  fprintf(out, " --- Section %d size=%d ---\n", i, len);
99  Uint32 * signalData = ptr[i].p;
100  while(len >= 7){
101  fprintf(out,
102  " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
103  signalData[0], signalData[1], signalData[2], signalData[3],
104  signalData[4], signalData[5], signalData[6]);
105  len -= 7;
106  signalData += 7;
107  }
108  if(len > 0){
109  fprintf(out, " H\'%.8x", signalData[0]);
110  for(Uint32 i = 1; i<len; i++)
111  fprintf(out, " H\'%.8x", signalData[i]);
112  fprintf(out, "\n");
113  }
114  }
115 }
116 
117 SignalSender::SignalSender(TransporterFacade *facade, int blockNo)
118 {
119  theFacade = facade;
120  Uint32 res = open(theFacade, blockNo);
121  assert(res != 0);
122  m_blockNo = refToBlock(res);
123 }
124 
125 SignalSender::SignalSender(Ndb_cluster_connection* connection)
126 {
127  theFacade = connection->m_impl.m_transporter_facade;
128  Uint32 res = open(theFacade, -1);
129  assert(res != 0);
130  m_blockNo = refToBlock(res);
131 }
132 
133 SignalSender::~SignalSender(){
134  int i;
135  unlock();
136  close();
137 
138  // free these _after_ closing theFacade to ensure that
139  // we delete all signals
140  for (i= m_jobBuffer.size()-1; i>= 0; i--)
141  delete m_jobBuffer[i];
142  for (i= m_usedBuffer.size()-1; i>= 0; i--)
143  delete m_usedBuffer[i];
144 }
145 
146 int SignalSender::lock()
147 {
148  start_poll();
149  return 0;
150 }
151 
152 int SignalSender::unlock()
153 {
154  complete_poll();
155  return 0;
156 }
157 
158 Uint32
159 SignalSender::getOwnRef() const {
160  return numberToRef(m_blockNo, theFacade->ownId());
161 }
162 
164 SignalSender::broadcastSignal(NodeBitmask mask,
165  SimpleSignal& sig,
166  Uint16 recBlock, Uint16 gsn,
167  Uint32 len)
168 {
169  sig.set(*this, TestOrd::TraceAPI, recBlock, gsn, len);
170 
171  NodeBitmask result;
172  for(Uint32 i = 0; i < MAX_NODES; i++)
173  {
174  if(mask.get(i) && sendSignal(i, &sig) == SEND_OK)
175  result.set(i);
176  }
177  return result;
178 }
179 
180 
181 SendStatus
182 SignalSender::sendSignal(Uint16 nodeId,
183  SimpleSignal& sig,
184  Uint16 recBlock, Uint16 gsn,
185  Uint32 len)
186 {
187  sig.set(*this, TestOrd::TraceAPI, recBlock, gsn, len);
188  return sendSignal(nodeId, &sig);
189 }
190 
191 int
192 SignalSender::sendFragmentedSignal(Uint16 nodeId,
193  SimpleSignal& sig,
194  Uint16 recBlock, Uint16 gsn,
195  Uint32 len)
196 {
197  sig.set(*this, TestOrd::TraceAPI, recBlock, gsn, len);
198 
199  int ret = raw_sendFragmentedSignal(&sig.header,
200  nodeId,
201  &sig.ptr[0],
202  sig.header.m_noOfSections);
203  if (ret == 0)
204  {
205  do_forceSend();
206  return SEND_OK;
207  }
208  return SEND_DISCONNECTED;
209 }
210 
211 SendStatus
212 SignalSender::sendSignal(Uint16 nodeId, const SimpleSignal * s)
213 {
214  int ret = raw_sendSignal((NdbApiSignal*)&s->header,
215  nodeId,
216  s->ptr,
217  s->header.m_noOfSections);
218  if (ret == 0)
219  {
220  do_forceSend();
221  return SEND_OK;
222  }
223  return SEND_DISCONNECTED;
224 }
225 
226 template<class T>
227 SimpleSignal *
228 SignalSender::waitFor(Uint32 timeOutMillis, T & t)
229 {
230  SimpleSignal * s = t.check(m_jobBuffer);
231  if(s != 0){
232  if (m_usedBuffer.push_back(s))
233  {
234  return 0;
235  }
236  assert(s->header.theLength > 0);
237  return s;
238  }
239 
240  /* Remove old signals from usedBuffer */
241  for (unsigned i= 0; i < m_usedBuffer.size(); i++)
242  delete m_usedBuffer[i];
243  m_usedBuffer.clear();
244 
245  NDB_TICKS now = NdbTick_CurrentMillisecond();
246  NDB_TICKS stop = now + timeOutMillis;
247  Uint32 wait = (timeOutMillis == 0 ? 10 : timeOutMillis);
248  do {
249  do_poll(wait);
250 
251  SimpleSignal * s = t.check(m_jobBuffer);
252  if(s != 0){
253  if (m_usedBuffer.push_back(s))
254  {
255  return 0;
256  }
257  assert(s->header.theLength > 0);
258  return s;
259  }
260 
261  now = NdbTick_CurrentMillisecond();
262  wait = (Uint32)(timeOutMillis == 0 ? 10 : stop - now);
263  } while(stop > now || timeOutMillis == 0);
264 
265  return 0;
266 }
267 
268 class WaitForAny {
269 public:
270  WaitForAny() {}
271  SimpleSignal * check(Vector<SimpleSignal*> & m_jobBuffer){
272  if(m_jobBuffer.size() > 0){
273  SimpleSignal * s = m_jobBuffer[0];
274  m_jobBuffer.erase(0);
275  return s;
276  }
277  return 0;
278  }
279 };
280 
281 SimpleSignal *
282 SignalSender::waitFor(Uint32 timeOutMillis){
283 
284  WaitForAny w;
285  return waitFor(timeOutMillis, w);
286 }
287 
288 #include <NdbApiSignal.hpp>
289 
290 void
292  const struct LinearSectionPtr ptr[3])
293 {
294  SimpleSignal * s = new SimpleSignal(true);
295  s->header = * signal;
296  for(Uint32 i = 0; i<s->header.m_noOfSections; i++){
297  s->ptr[i].p = new Uint32[ptr[i].sz];
298  s->ptr[i].sz = ptr[i].sz;
299  memcpy(s->ptr[i].p, ptr[i].p, 4 * ptr[i].sz);
300  }
301  m_jobBuffer.push_back(s);
302  wakeup();
303 }
304 
305 template<class T>
306 NodeId
307 SignalSender::find_node(const NodeBitmask& mask, T & t)
308 {
309  unsigned n= 0;
310  do {
311  n= mask.find(n+1);
312 
313  if (n == NodeBitmask::NotFound)
314  return 0;
315 
316  assert(n < MAX_NODES);
317 
318  } while (!t.found_ok(*this, getNodeInfo(n)));
319 
320  return n;
321 }
322 
323 
325 public:
326  bool found_ok(const SignalSender& ss, const trp_node & node){
327  return node.is_confirmed();
328  }
329 };
330 
331 
332 NodeId
333 SignalSender::find_confirmed_node(const NodeBitmask& mask)
334 {
336  return find_node(mask, f);
337 }
338 
339 
341 public:
342  bool found_ok(const SignalSender& ss, const trp_node & node){
343  return node.is_connected();
344  }
345 };
346 
347 
348 NodeId
349 SignalSender::find_connected_node(const NodeBitmask& mask)
350 {
352  return find_node(mask, f);
353 }
354 
355 
357 public:
358  bool found_ok(const SignalSender& ss, const trp_node & node){
359  return node.m_alive;
360  }
361 };
362 
363 
364 NodeId
365 SignalSender::find_alive_node(const NodeBitmask& mask)
366 {
367  FindAliveNode f;
368  return find_node(mask, f);
369 }
370 
371 
372 #if __SUNPRO_CC != 0x560
373 template SimpleSignal* SignalSender::waitFor<WaitForAny>(unsigned, WaitForAny&);
374 template NodeId SignalSender::find_node<FindConfirmedNode>(const NodeBitmask&,
376 template NodeId SignalSender::find_node<FindAliveNode>(const NodeBitmask&,
377  FindAliveNode&);
378 template NodeId SignalSender::find_node<FindConnectedNode>(const NodeBitmask&,
380 #endif
381 template class Vector<SimpleSignal*>;
382