1 /* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef NDB_DBLQH_PROXY_HPP
24 #define NDB_DBLQH_PROXY_HPP
25 
26 #include <LocalProxy.hpp>
27 #include <signaldata/CreateTab.hpp>
28 #include <signaldata/LqhFrag.hpp>
29 #include <signaldata/TabCommit.hpp>
30 #include <signaldata/LCP.hpp>
31 #include <signaldata/GCP.hpp>
32 #include <signaldata/PrepDropTab.hpp>
33 #include <signaldata/DropTab.hpp>
34 #include <signaldata/AlterTab.hpp>
35 #include <signaldata/StartRec.hpp>
36 #include <signaldata/LqhTransReq.hpp>
37 #include <signaldata/LqhTransConf.hpp>
38 
39 #define JAM_FILE_ID 445
40 
41 
42 class DblqhProxy : public LocalProxy {
43 public:
44   DblqhProxy(Block_context& ctx);
45   virtual ~DblqhProxy();
46   BLOCK_DEFINES(DblqhProxy);
47 
48 protected:
49   virtual SimulatedBlock* newWorker(Uint32 instanceNo);
50 
51   // system info
52   Uint32 c_tableRecSize;
53   Uint8* c_tableRec;    // bool => table exists
54 
55   // GSN_NDB_STTOR
56   virtual void callNDB_STTOR(Signal*);
57   virtual void callREAD_CONFIG_REQ(Signal*);
58 
59   // GSN_CREATE_TAB_REQ
60   struct Ss_CREATE_TAB_REQ : SsParallel {
61     CreateTabReq m_req;
62     Uint32 m_lqhConnectPtr[MaxWorkers];
Ss_CREATE_TAB_REQDblqhProxy::Ss_CREATE_TAB_REQ63     Ss_CREATE_TAB_REQ() {
64       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendCREATE_TAB_REQ;
65       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendCREATE_TAB_CONF;
66     }
67     enum { poolSize = 1 };
poolDblqhProxy::Ss_CREATE_TAB_REQ68     static SsPool<Ss_CREATE_TAB_REQ>& pool(LocalProxy* proxy) {
69       return ((DblqhProxy*)proxy)->c_ss_CREATE_TAB_REQ;
70     }
71   };
72   SsPool<Ss_CREATE_TAB_REQ> c_ss_CREATE_TAB_REQ;
73   void execCREATE_TAB_REQ(Signal*);
74   void sendCREATE_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
75   void execCREATE_TAB_CONF(Signal*);
76   void execCREATE_TAB_REF(Signal*);
77   void sendCREATE_TAB_CONF(Signal*, Uint32 ssId);
78 
79   // GSN_LQHADDATTREQ [ sub-op ]
80   struct Ss_LQHADDATTREQ : SsParallel {
81     LqhAddAttrReq m_req;
82     Uint32 m_reqlength;
Ss_LQHADDATTREQDblqhProxy::Ss_LQHADDATTREQ83     Ss_LQHADDATTREQ() {
84       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendLQHADDATTREQ;
85       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendLQHADDATTCONF;
86     }
87     enum { poolSize = 1 };
poolDblqhProxy::Ss_LQHADDATTREQ88     static SsPool<Ss_LQHADDATTREQ>& pool(LocalProxy* proxy) {
89       return ((DblqhProxy*)proxy)->c_ss_LQHADDATTREQ;
90     }
91   };
92   SsPool<Ss_LQHADDATTREQ> c_ss_LQHADDATTREQ;
93   void execLQHADDATTREQ(Signal*);
94   void sendLQHADDATTREQ(Signal*, Uint32 ssId, SectionHandle*);
95   void execLQHADDATTCONF(Signal*);
96   void execLQHADDATTREF(Signal*);
97   void sendLQHADDATTCONF(Signal*, Uint32 ssId);
98 
99   // GSN_LQHFRAGREQ [ pass-through ]
100   void execLQHFRAGREQ(Signal*);
101 
102   // GSN_TAB_COMMITREQ [ sub-op ]
103   struct Ss_TAB_COMMITREQ : SsParallel {
104     TabCommitReq m_req;
Ss_TAB_COMMITREQDblqhProxy::Ss_TAB_COMMITREQ105     Ss_TAB_COMMITREQ() {
106       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendTAB_COMMITREQ;
107       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendTAB_COMMITCONF;
108     }
109     enum { poolSize = 1 };
poolDblqhProxy::Ss_TAB_COMMITREQ110     static SsPool<Ss_TAB_COMMITREQ>& pool(LocalProxy* proxy) {
111       return ((DblqhProxy*)proxy)->c_ss_TAB_COMMITREQ;
112     }
113   };
114   SsPool<Ss_TAB_COMMITREQ> c_ss_TAB_COMMITREQ;
115   void execTAB_COMMITREQ(Signal*);
116   void sendTAB_COMMITREQ(Signal*, Uint32 ssId, SectionHandle*);
117   void execTAB_COMMITCONF(Signal*);
118   void execTAB_COMMITREF(Signal*);
119   void sendTAB_COMMITCONF(Signal*, Uint32 ssId);
120 
121   // GSN_GCP_SAVEREQ
122   struct Ss_GCP_SAVEREQ : SsParallel {
nameDblqhProxy::Ss_GCP_SAVEREQ123     static const char* name() { return "GCP_SAVEREQ"; }
124     GCPSaveReq m_req;
Ss_GCP_SAVEREQDblqhProxy::Ss_GCP_SAVEREQ125     Ss_GCP_SAVEREQ() {
126       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendGCP_SAVEREQ;
127       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendGCP_SAVECONF;
128     }
129     enum { poolSize = 1 };
poolDblqhProxy::Ss_GCP_SAVEREQ130     static SsPool<Ss_GCP_SAVEREQ>& pool(LocalProxy* proxy) {
131       return ((DblqhProxy*)proxy)->c_ss_GCP_SAVEREQ;
132     }
133   };
134   SsPool<Ss_GCP_SAVEREQ> c_ss_GCP_SAVEREQ;
getSsId(const GCPSaveReq * req)135   Uint32 getSsId(const GCPSaveReq* req) {
136     return SsIdBase | (req->gci & 0xFFFF);
137   }
getSsId(const GCPSaveConf * conf)138   Uint32 getSsId(const GCPSaveConf* conf) {
139     return SsIdBase | (conf->gci & 0xFFFF);
140   }
getSsId(const GCPSaveRef * ref)141   Uint32 getSsId(const GCPSaveRef* ref) {
142     return SsIdBase | (ref->gci & 0xFFFF);
143   }
144   void execGCP_SAVEREQ(Signal*);
145   void sendGCP_SAVEREQ(Signal*, Uint32 ssId, SectionHandle*);
146   void execGCP_SAVECONF(Signal*);
147   void execGCP_SAVEREF(Signal*);
148   void sendGCP_SAVECONF(Signal*, Uint32 ssId);
149 
150   // GSN_SUB_GCP_COMPLETE_REP
151   void execSUB_GCP_COMPLETE_REP(Signal*);
152 
153   // GSN_START_LCP_ORD
154   void execSTART_LCP_ORD(Signal*);
155 
156   // GSN_UNDO_LOG_LEVEL_REP
157   void execUNDO_LOG_LEVEL_REP(Signal*);
158 
159   // GSN_PREP_DROP_TAB_REQ
160   struct Ss_PREP_DROP_TAB_REQ : SsParallel {
161     PrepDropTabReq m_req;
Ss_PREP_DROP_TAB_REQDblqhProxy::Ss_PREP_DROP_TAB_REQ162     Ss_PREP_DROP_TAB_REQ() {
163       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendPREP_DROP_TAB_REQ;
164       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendPREP_DROP_TAB_CONF;
165     }
166     enum { poolSize = 1 };
poolDblqhProxy::Ss_PREP_DROP_TAB_REQ167     static SsPool<Ss_PREP_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
168       return ((DblqhProxy*)proxy)->c_ss_PREP_DROP_TAB_REQ;
169     }
170   };
171   SsPool<Ss_PREP_DROP_TAB_REQ> c_ss_PREP_DROP_TAB_REQ;
getSsId(const PrepDropTabReq * req)172   Uint32 getSsId(const PrepDropTabReq* req) {
173     return SsIdBase | req->tableId;
174   }
getSsId(const PrepDropTabConf * conf)175   Uint32 getSsId(const PrepDropTabConf* conf) {
176     return SsIdBase | conf->tableId;
177   }
getSsId(const PrepDropTabRef * ref)178   Uint32 getSsId(const PrepDropTabRef* ref) {
179     return SsIdBase | ref->tableId;
180   }
181   void execPREP_DROP_TAB_REQ(Signal*);
182   void sendPREP_DROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
183   void execPREP_DROP_TAB_CONF(Signal*);
184   void execPREP_DROP_TAB_REF(Signal*);
185   void sendPREP_DROP_TAB_CONF(Signal*, Uint32 ssId);
186 
187   // GSN_DROP_TAB_REQ
188   struct Ss_DROP_TAB_REQ : SsParallel {
189     DropTabReq m_req;
Ss_DROP_TAB_REQDblqhProxy::Ss_DROP_TAB_REQ190     Ss_DROP_TAB_REQ() {
191       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendDROP_TAB_REQ;
192       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendDROP_TAB_CONF;
193     }
194     enum { poolSize = 1 };
poolDblqhProxy::Ss_DROP_TAB_REQ195     static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
196       return ((DblqhProxy*)proxy)->c_ss_DROP_TAB_REQ;
197     }
198   };
199   SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
getSsId(const DropTabReq * req)200   Uint32 getSsId(const DropTabReq* req) {
201     return SsIdBase | req->tableId;
202   }
getSsId(const DropTabConf * conf)203   Uint32 getSsId(const DropTabConf* conf) {
204     return SsIdBase | conf->tableId;
205   }
getSsId(const DropTabRef * ref)206   Uint32 getSsId(const DropTabRef* ref) {
207     return SsIdBase | ref->tableId;
208   }
209   void execDROP_TAB_REQ(Signal*);
210   void sendDROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
211   void execDROP_TAB_CONF(Signal*);
212   void execDROP_TAB_REF(Signal*);
213   void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
214 
215   // GSN_ALTER_TAB_REQ
216   struct Ss_ALTER_TAB_REQ : SsParallel {
217     AlterTabReq m_req;
Ss_ALTER_TAB_REQDblqhProxy::Ss_ALTER_TAB_REQ218     Ss_ALTER_TAB_REQ() {
219       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendALTER_TAB_REQ;
220       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendALTER_TAB_CONF;
221     }
222     enum { poolSize = 1 };
poolDblqhProxy::Ss_ALTER_TAB_REQ223     static SsPool<Ss_ALTER_TAB_REQ>& pool(LocalProxy* proxy) {
224       return ((DblqhProxy*)proxy)->c_ss_ALTER_TAB_REQ;
225     }
226   };
227   SsPool<Ss_ALTER_TAB_REQ> c_ss_ALTER_TAB_REQ;
getSsId(const AlterTabReq * req)228   Uint32 getSsId(const AlterTabReq* req) {
229     return SsIdBase | req->tableId;
230   }
getSsId(const AlterTabConf * conf)231   Uint32 getSsId(const AlterTabConf* conf) {
232     return conf->senderData;
233   }
getSsId(const AlterTabRef * ref)234   Uint32 getSsId(const AlterTabRef* ref) {
235     return ref->senderData;
236   }
237   void execALTER_TAB_REQ(Signal*);
238   void sendALTER_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
239   void execALTER_TAB_CONF(Signal*);
240   void execALTER_TAB_REF(Signal*);
241   void sendALTER_TAB_CONF(Signal*, Uint32 ssId);
242 
243   /**
244    * GSN_START_FRAGREQ needs to be serialized wrt START_RECREQ
245    *   so send it via proxy, even if DIH knows where to send it...
246    */
247   void execSTART_FRAGREQ(Signal*);
248 
249   // GSN_START_RECREQ
250   struct Ss_START_RECREQ : SsParallel {
251     /*
252      * The proxy is also proxy for signals from workers to global
253      * blocks LGMAN, TSMAN.  These are run (sequentially) using
254      * the sub-op START_RECREQ_2.
255      */
nameDblqhProxy::Ss_START_RECREQ256     static const char* name() { return "START_RECREQ"; }
257     StartRecReq m_req;
258     Uint32 phaseToSend;
259     Uint32 restoreFragCompletedCount;
260     Uint32 undoDDCompletedCount;
261     Uint32 execREDOLogCompletedCount;
262     // pointers to START_RECREQ_2 for LGMAN, TSMAN
263     enum { m_req2cnt = 2 };
264     struct {
265       Uint32 m_blockNo;
266       Uint32 m_ssId;
267     } m_req2[m_req2cnt];
Ss_START_RECREQDblqhProxy::Ss_START_RECREQ268     Ss_START_RECREQ() {
269       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendSTART_RECREQ;
270       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendSTART_RECCONF;
271       m_req2[0].m_blockNo = LGMAN;
272       m_req2[1].m_blockNo = TSMAN;
273     }
274     enum { poolSize = 1 };
poolDblqhProxy::Ss_START_RECREQ275     static SsPool<Ss_START_RECREQ>& pool(LocalProxy* proxy) {
276       return ((DblqhProxy*)proxy)->c_ss_START_RECREQ;
277     }
278   };
279   SsPool<Ss_START_RECREQ> c_ss_START_RECREQ;
280   void execSTART_RECREQ(Signal*);
281   void sendSTART_RECREQ(Signal*, Uint32 ssId, SectionHandle*);
282   void execSTART_RECCONF(Signal*);
283   void execLOCAL_RECOVERY_COMP_REP(Signal*);
284   void sendSTART_RECCONF(Signal*, Uint32 ssId);
285 
286   // GSN_START_RECREQ_2 [ sub-op, fictional gsn ]
287   struct Ss_START_RECREQ_2 : SsParallel {
nameDblqhProxy::Ss_START_RECREQ_2288     static const char* name() { return "START_RECREQ_2"; }
289     struct Req {
290       enum { SignalLength = 3 };
291       Uint32 lcpId;
292       Uint32 localLcpId;
293       Uint32 proxyBlockNo;
294     };
295     // senderData is unnecessary as signal is unique per proxyBlockNo
296     struct Conf {
297       enum { SignalLength = 1 };
298       Uint32 senderRef;
299     };
300     Req m_req;
301     Conf m_conf;
Ss_START_RECREQ_2DblqhProxy::Ss_START_RECREQ_2302     Ss_START_RECREQ_2() {
303       // reversed sendREQ/sendCONF
304       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendSTART_RECCONF_2;
305       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendSTART_RECREQ_2;
306     }
307     enum { poolSize = 2 };
poolDblqhProxy::Ss_START_RECREQ_2308     static SsPool<Ss_START_RECREQ_2>& pool(LocalProxy* proxy) {
309       return ((DblqhProxy*)proxy)->c_ss_START_RECREQ_2;
310     }
311   };
312   SsPool<Ss_START_RECREQ_2> c_ss_START_RECREQ_2;
getSsId(const Ss_START_RECREQ_2::Req * req)313   Uint32 getSsId(const Ss_START_RECREQ_2::Req* req) {
314     return SsIdBase | req->proxyBlockNo;
315   }
getSsId(const Ss_START_RECREQ_2::Conf * conf)316   Uint32 getSsId(const Ss_START_RECREQ_2::Conf* conf) {
317     return SsIdBase | refToBlock(conf->senderRef);
318   }
319   void execSTART_RECREQ_2(Signal*);
320   void sendSTART_RECREQ_2(Signal*, Uint32 ssId);
321   void execSTART_RECCONF_2(Signal*);
322   void sendSTART_RECCONF_2(Signal*, Uint32 ssId, SectionHandle*);
323 
324   // GSN_LQH_TRANSREQ
325   struct Ss_LQH_TRANSREQ : SsParallel {
nameDblqhProxy::Ss_LQH_TRANSREQ326     static const char* name() { return "LQH_TRANSREQ"; }
327     /**
328      * Is this entry valid, or has it been made obsolete by
329      *   a new LQH_TRANSREQ (i.e a new TC-failure)
330      */
331     bool m_valid;
332     Uint32 m_maxInstanceId;
333     LqhTransReq m_req;
334     LqhTransConf m_conf; // latest conf
Ss_LQH_TRANSREQDblqhProxy::Ss_LQH_TRANSREQ335     Ss_LQH_TRANSREQ() {
336       m_valid = true;
337       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendLQH_TRANSREQ;
338       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendLQH_TRANSCONF;
339     }
340     enum { poolSize = MAX_NDB_NODES };
poolDblqhProxy::Ss_LQH_TRANSREQ341     static SsPool<Ss_LQH_TRANSREQ>& pool(LocalProxy* proxy) {
342       return ((DblqhProxy*)proxy)->c_ss_LQH_TRANSREQ;
343     }
344   };
345   SsPool<Ss_LQH_TRANSREQ> c_ss_LQH_TRANSREQ;
346   void execLQH_TRANSREQ(Signal*);
347   void sendLQH_TRANSREQ(Signal*, Uint32 ssId, SectionHandle*);
348   void execLQH_TRANSCONF(Signal*);
349   void sendLQH_TRANSCONF(Signal*, Uint32 ssId);
350 
351   // GSN_EXEC_SR_1 [ fictional gsn ]
352   struct Ss_EXEC_SR_1 : SsParallel {
353     /*
354      * Handle EXEC_SRREQ and EXEC_SRCONF.  These are broadcast
355      * signals (not REQ/CONF).  EXEC_SR_1 receives one signal and
356      * sends it to its workers.  EXEC_SR_2 waits for signal from
357      * all workers and broadcasts it to all nodes.  These are
358      * required to handle mixed versions (non-mt, mt-lqh-1,2,4).
359      */
nameDblqhProxy::Ss_EXEC_SR_1360     static const char* name() { return "EXEC_SR_1"; }
361     struct Sig {
362       enum { SignalLength = 1 };
363       Uint32 nodeId;
364     };
365     GlobalSignalNumber m_gsn;
366     Sig m_sig;
Ss_EXEC_SR_1DblqhProxy::Ss_EXEC_SR_1367     Ss_EXEC_SR_1() {
368       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendEXEC_SR_1;
369       m_sendCONF = (SsFUNCREP)0;
370       m_gsn = 0;
371     }
372     enum { poolSize = 1 };
poolDblqhProxy::Ss_EXEC_SR_1373     static SsPool<Ss_EXEC_SR_1>& pool(LocalProxy* proxy) {
374       return ((DblqhProxy*)proxy)->c_ss_EXEC_SR_1;
375     }
376   };
377   SsPool<Ss_EXEC_SR_1> c_ss_EXEC_SR_1;
getSsId(const Ss_EXEC_SR_1::Sig * sig)378   Uint32 getSsId(const Ss_EXEC_SR_1::Sig* sig) {
379     return SsIdBase | refToNode(sig->nodeId);
380   }
381   void execEXEC_SRREQ(Signal*);
382   void execEXEC_SRCONF(Signal*);
383   void execEXEC_SR_1(Signal*, GlobalSignalNumber gsn);
384   void sendEXEC_SR_1(Signal*, Uint32 ssId, SectionHandle*);
385 
386   // GSN_EXEC_SR_2 [ fictional gsn ]
387   struct Ss_EXEC_SR_2 : SsParallel {
nameDblqhProxy::Ss_EXEC_SR_2388     static const char* name() { return "EXEC_SR_2"; }
389     struct Sig {
390       enum { SignalLength = 1 + NdbNodeBitmask::Size };
391       Uint32 nodeId;
392       Uint32 sr_nodes[NdbNodeBitmask::Size]; // local signal so ok to add
393     };
394     GlobalSignalNumber m_gsn;
395     Uint32 m_sigcount;
396     Sig m_sig; // all signals must be identical
Ss_EXEC_SR_2DblqhProxy::Ss_EXEC_SR_2397     Ss_EXEC_SR_2() {
398       // reversed roles
399       m_sendREQ = (SsFUNCREQ)0;
400       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendEXEC_SR_2;
401       m_gsn = 0;
402       m_sigcount = 0;
403     }
404     enum { poolSize = 1 };
poolDblqhProxy::Ss_EXEC_SR_2405     static SsPool<Ss_EXEC_SR_2>& pool(LocalProxy* proxy) {
406       return ((DblqhProxy*)proxy)->c_ss_EXEC_SR_2;
407     }
408   };
409   SsPool<Ss_EXEC_SR_2> c_ss_EXEC_SR_2;
getSsId(const Ss_EXEC_SR_2::Sig * sig)410   Uint32 getSsId(const Ss_EXEC_SR_2::Sig* sig) {
411     return SsIdBase | refToNode(sig->nodeId);
412   }
413   void execEXEC_SR_2(Signal*, GlobalSignalNumber gsn);
414   void sendEXEC_SR_2(Signal*, Uint32 ssId);
415 
416   /**
417    * GSN_EXEC_FRAGREQ & GSN_EXEC_FRAGCONF needs to
418    *   be passed via proxy for correct serialization
419    *   wrt to GSN_EXEC_SRREQ & GSN_EXEC_SRCONF
420    */
421   void execEXEC_FRAGREQ(Signal*);
422   void execEXEC_FRAGCONF(Signal*);
423 
424   // GSN_DROP_FRAG_REQ
425   struct Ss_DROP_FRAG_REQ : SsParallel {
426     DropFragReq m_req;
Ss_DROP_FRAG_REQDblqhProxy::Ss_DROP_FRAG_REQ427     Ss_DROP_FRAG_REQ() {
428       m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendDROP_FRAG_REQ;
429       m_sendCONF = (SsFUNCREP)&DblqhProxy::sendDROP_FRAG_CONF;
430     }
431     enum { poolSize = 1 };
poolDblqhProxy::Ss_DROP_FRAG_REQ432     static SsPool<Ss_DROP_FRAG_REQ>& pool(LocalProxy* proxy) {
433       return ((DblqhProxy*)proxy)->c_ss_DROP_FRAG_REQ;
434     }
435   };
436   SsPool<Ss_DROP_FRAG_REQ> c_ss_DROP_FRAG_REQ;
getSsId(const DropFragReq * req)437   Uint32 getSsId(const DropFragReq* req) {
438     return SsIdBase | (req->tableId ^ req->fragId);
439   }
getSsId(const DropFragConf * conf)440   Uint32 getSsId(const DropFragConf* conf) {
441     return SsIdBase | (conf->tableId ^ conf->fragId);
442   }
getSsId(const DropFragRef * ref)443   Uint32 getSsId(const DropFragRef* ref) {
444     return SsIdBase | (ref->tableId ^ ref->fragId);
445   }
446   void execDROP_FRAG_REQ(Signal*);
447   void sendDROP_FRAG_REQ(Signal*, Uint32 ssId, SectionHandle*);
448   void execDROP_FRAG_CONF(Signal*);
449   void execDROP_FRAG_REF(Signal*);
450   void sendDROP_FRAG_CONF(Signal*, Uint32 ssId);
451 
452   // LCP handling
453   void execLCP_FRAG_ORD(Signal*);
454   void execLCP_FRAG_REP(Signal*);
455   void execEND_LCPCONF(Signal*);
456   void execLCP_COMPLETE_REP(Signal*);
457   void execWAIT_ALL_COMPLETE_LCP_REQ(Signal*);
458   void execWAIT_COMPLETE_LCP_CONF(Signal*);
459   void execINFO_GCP_STOP_TIMER(Signal*);
460   void execSTART_NODE_LCP_REQ(Signal*);
461   void execSTART_NODE_LCP_CONF(Signal*);
462 
463   Uint32 m_outstanding_wait_lcp;
464   BlockReference m_wait_all_lcp_sender;
465   bool m_received_wait_all;
466   bool m_lcp_started;
467   Uint32 m_outstanding_start_node_lcp_req;
468 
469   struct LcpRecord {
470     enum {
471       L_IDLE         = 0,
472       L_RUNNING      = 1,
473       L_COMPLETING_1 = 2,
474       L_COMPLETING_2 = 3
475     } m_state;
476     Uint32 m_lcpId;
477     Uint32 m_keepGci;
478     Uint32 m_lcp_frag_ord_cnt;     // No of LCP_FRAG_ORD received
479     Uint32 m_lcp_frag_rep_cnt;     // No of LCP_FRAG_REP sent
480     Uint32 m_complete_outstanding; // Outstanding signals waiting for
481     LcpFragOrd m_last_lcp_frag_ord;// Last received LCP_FRAG_ORD
482     bool m_lastFragmentFlag;
483 
LcpRecordDblqhProxy::LcpRecord484     LcpRecord(){
485       m_state = L_IDLE;
486       m_lcpId = 0;
487       m_lcp_frag_ord_cnt = 0;
488       m_lcp_frag_rep_cnt = 0;
489       m_lastFragmentFlag = false;
490     }
491   };
492   LcpRecord c_lcpRecord;
493   Uint32 getNoOfOutstanding(const LcpRecord&) const;
494   void completeLCP(Signal* signal);
495   void sendLCP_COMPLETE_REP(Signal*);
496 };
497 
498 
499 #undef JAM_FILE_ID
500 
501 #endif
502