1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates. 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 Street, 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 #include <signaldata/EmptyLcp.hpp> 39 40 #define JAM_FILE_ID 445 41 42 43 class DblqhProxy : public LocalProxy { 44 public: 45 DblqhProxy(Block_context& ctx); 46 virtual ~DblqhProxy(); 47 BLOCK_DEFINES(DblqhProxy); 48 49 protected: 50 virtual SimulatedBlock* newWorker(Uint32 instanceNo); 51 52 // system info 53 Uint32 c_tableRecSize; 54 Uint8* c_tableRec; // bool => table exists 55 56 // GSN_NDB_STTOR 57 virtual void callNDB_STTOR(Signal*); 58 virtual void callREAD_CONFIG_REQ(Signal*); 59 60 // GSN_CREATE_TAB_REQ 61 struct Ss_CREATE_TAB_REQ : SsParallel { 62 CreateTabReq m_req; 63 Uint32 m_lqhConnectPtr[MaxWorkers]; Ss_CREATE_TAB_REQDblqhProxy::Ss_CREATE_TAB_REQ64 Ss_CREATE_TAB_REQ() { 65 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendCREATE_TAB_REQ; 66 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendCREATE_TAB_CONF; 67 } 68 enum { poolSize = 1 }; poolDblqhProxy::Ss_CREATE_TAB_REQ69 static SsPool<Ss_CREATE_TAB_REQ>& pool(LocalProxy* proxy) { 70 return ((DblqhProxy*)proxy)->c_ss_CREATE_TAB_REQ; 71 } 72 }; 73 SsPool<Ss_CREATE_TAB_REQ> c_ss_CREATE_TAB_REQ; 74 void execCREATE_TAB_REQ(Signal*); 75 void sendCREATE_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*); 76 void execCREATE_TAB_CONF(Signal*); 77 void execCREATE_TAB_REF(Signal*); 78 void sendCREATE_TAB_CONF(Signal*, Uint32 ssId); 79 80 // GSN_LQHADDATTREQ [ sub-op ] 81 struct Ss_LQHADDATTREQ : SsParallel { 82 LqhAddAttrReq m_req; 83 Uint32 m_reqlength; Ss_LQHADDATTREQDblqhProxy::Ss_LQHADDATTREQ84 Ss_LQHADDATTREQ() { 85 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendLQHADDATTREQ; 86 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendLQHADDATTCONF; 87 } 88 enum { poolSize = 1 }; poolDblqhProxy::Ss_LQHADDATTREQ89 static SsPool<Ss_LQHADDATTREQ>& pool(LocalProxy* proxy) { 90 return ((DblqhProxy*)proxy)->c_ss_LQHADDATTREQ; 91 } 92 }; 93 SsPool<Ss_LQHADDATTREQ> c_ss_LQHADDATTREQ; 94 void execLQHADDATTREQ(Signal*); 95 void sendLQHADDATTREQ(Signal*, Uint32 ssId, SectionHandle*); 96 void execLQHADDATTCONF(Signal*); 97 void execLQHADDATTREF(Signal*); 98 void sendLQHADDATTCONF(Signal*, Uint32 ssId); 99 100 // GSN_LQHFRAGREQ [ pass-through ] 101 void execLQHFRAGREQ(Signal*); 102 103 // GSN_TAB_COMMITREQ [ sub-op ] 104 struct Ss_TAB_COMMITREQ : SsParallel { 105 TabCommitReq m_req; Ss_TAB_COMMITREQDblqhProxy::Ss_TAB_COMMITREQ106 Ss_TAB_COMMITREQ() { 107 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendTAB_COMMITREQ; 108 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendTAB_COMMITCONF; 109 } 110 enum { poolSize = 1 }; poolDblqhProxy::Ss_TAB_COMMITREQ111 static SsPool<Ss_TAB_COMMITREQ>& pool(LocalProxy* proxy) { 112 return ((DblqhProxy*)proxy)->c_ss_TAB_COMMITREQ; 113 } 114 }; 115 SsPool<Ss_TAB_COMMITREQ> c_ss_TAB_COMMITREQ; 116 void execTAB_COMMITREQ(Signal*); 117 void sendTAB_COMMITREQ(Signal*, Uint32 ssId, SectionHandle*); 118 void execTAB_COMMITCONF(Signal*); 119 void execTAB_COMMITREF(Signal*); 120 void sendTAB_COMMITCONF(Signal*, Uint32 ssId); 121 122 // GSN_GCP_SAVEREQ 123 struct Ss_GCP_SAVEREQ : SsParallel { nameDblqhProxy::Ss_GCP_SAVEREQ124 static const char* name() { return "GCP_SAVEREQ"; } 125 GCPSaveReq m_req; Ss_GCP_SAVEREQDblqhProxy::Ss_GCP_SAVEREQ126 Ss_GCP_SAVEREQ() { 127 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendGCP_SAVEREQ; 128 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendGCP_SAVECONF; 129 } 130 enum { poolSize = 1 }; poolDblqhProxy::Ss_GCP_SAVEREQ131 static SsPool<Ss_GCP_SAVEREQ>& pool(LocalProxy* proxy) { 132 return ((DblqhProxy*)proxy)->c_ss_GCP_SAVEREQ; 133 } 134 }; 135 SsPool<Ss_GCP_SAVEREQ> c_ss_GCP_SAVEREQ; getSsId(const GCPSaveReq * req)136 Uint32 getSsId(const GCPSaveReq* req) { 137 return SsIdBase | (req->gci & 0xFFFF); 138 } getSsId(const GCPSaveConf * conf)139 Uint32 getSsId(const GCPSaveConf* conf) { 140 return SsIdBase | (conf->gci & 0xFFFF); 141 } getSsId(const GCPSaveRef * ref)142 Uint32 getSsId(const GCPSaveRef* ref) { 143 return SsIdBase | (ref->gci & 0xFFFF); 144 } 145 void execGCP_SAVEREQ(Signal*); 146 void sendGCP_SAVEREQ(Signal*, Uint32 ssId, SectionHandle*); 147 void execGCP_SAVECONF(Signal*); 148 void execGCP_SAVEREF(Signal*); 149 void sendGCP_SAVECONF(Signal*, Uint32 ssId); 150 151 // GSN_SUB_GCP_COMPLETE_REP 152 void execSUB_GCP_COMPLETE_REP(Signal*); 153 154 // GSN_PREP_DROP_TAB_REQ 155 struct Ss_PREP_DROP_TAB_REQ : SsParallel { 156 PrepDropTabReq m_req; Ss_PREP_DROP_TAB_REQDblqhProxy::Ss_PREP_DROP_TAB_REQ157 Ss_PREP_DROP_TAB_REQ() { 158 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendPREP_DROP_TAB_REQ; 159 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendPREP_DROP_TAB_CONF; 160 } 161 enum { poolSize = 1 }; poolDblqhProxy::Ss_PREP_DROP_TAB_REQ162 static SsPool<Ss_PREP_DROP_TAB_REQ>& pool(LocalProxy* proxy) { 163 return ((DblqhProxy*)proxy)->c_ss_PREP_DROP_TAB_REQ; 164 } 165 }; 166 SsPool<Ss_PREP_DROP_TAB_REQ> c_ss_PREP_DROP_TAB_REQ; getSsId(const PrepDropTabReq * req)167 Uint32 getSsId(const PrepDropTabReq* req) { 168 return SsIdBase | req->tableId; 169 } getSsId(const PrepDropTabConf * conf)170 Uint32 getSsId(const PrepDropTabConf* conf) { 171 return SsIdBase | conf->tableId; 172 } getSsId(const PrepDropTabRef * ref)173 Uint32 getSsId(const PrepDropTabRef* ref) { 174 return SsIdBase | ref->tableId; 175 } 176 void execPREP_DROP_TAB_REQ(Signal*); 177 void sendPREP_DROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*); 178 void execPREP_DROP_TAB_CONF(Signal*); 179 void execPREP_DROP_TAB_REF(Signal*); 180 void sendPREP_DROP_TAB_CONF(Signal*, Uint32 ssId); 181 182 // GSN_DROP_TAB_REQ 183 struct Ss_DROP_TAB_REQ : SsParallel { 184 DropTabReq m_req; Ss_DROP_TAB_REQDblqhProxy::Ss_DROP_TAB_REQ185 Ss_DROP_TAB_REQ() { 186 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendDROP_TAB_REQ; 187 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendDROP_TAB_CONF; 188 } 189 enum { poolSize = 1 }; poolDblqhProxy::Ss_DROP_TAB_REQ190 static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) { 191 return ((DblqhProxy*)proxy)->c_ss_DROP_TAB_REQ; 192 } 193 }; 194 SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ; getSsId(const DropTabReq * req)195 Uint32 getSsId(const DropTabReq* req) { 196 return SsIdBase | req->tableId; 197 } getSsId(const DropTabConf * conf)198 Uint32 getSsId(const DropTabConf* conf) { 199 return SsIdBase | conf->tableId; 200 } getSsId(const DropTabRef * ref)201 Uint32 getSsId(const DropTabRef* ref) { 202 return SsIdBase | ref->tableId; 203 } 204 void execDROP_TAB_REQ(Signal*); 205 void sendDROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*); 206 void execDROP_TAB_CONF(Signal*); 207 void execDROP_TAB_REF(Signal*); 208 void sendDROP_TAB_CONF(Signal*, Uint32 ssId); 209 210 // GSN_ALTER_TAB_REQ 211 struct Ss_ALTER_TAB_REQ : SsParallel { 212 AlterTabReq m_req; Ss_ALTER_TAB_REQDblqhProxy::Ss_ALTER_TAB_REQ213 Ss_ALTER_TAB_REQ() { 214 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendALTER_TAB_REQ; 215 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendALTER_TAB_CONF; 216 } 217 enum { poolSize = 1 }; poolDblqhProxy::Ss_ALTER_TAB_REQ218 static SsPool<Ss_ALTER_TAB_REQ>& pool(LocalProxy* proxy) { 219 return ((DblqhProxy*)proxy)->c_ss_ALTER_TAB_REQ; 220 } 221 }; 222 SsPool<Ss_ALTER_TAB_REQ> c_ss_ALTER_TAB_REQ; getSsId(const AlterTabReq * req)223 Uint32 getSsId(const AlterTabReq* req) { 224 return SsIdBase | req->tableId; 225 } getSsId(const AlterTabConf * conf)226 Uint32 getSsId(const AlterTabConf* conf) { 227 return conf->senderData; 228 } getSsId(const AlterTabRef * ref)229 Uint32 getSsId(const AlterTabRef* ref) { 230 return ref->senderData; 231 } 232 void execALTER_TAB_REQ(Signal*); 233 void sendALTER_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*); 234 void execALTER_TAB_CONF(Signal*); 235 void execALTER_TAB_REF(Signal*); 236 void sendALTER_TAB_CONF(Signal*, Uint32 ssId); 237 238 /** 239 * GSN_START_FRAGREQ needs to be serialized wrt START_RECREQ 240 * so send it via proxy, even if DIH knows where to send it... 241 */ 242 void execSTART_FRAGREQ(Signal*); 243 244 // GSN_START_RECREQ 245 struct Ss_START_RECREQ : SsParallel { 246 /* 247 * The proxy is also proxy for signals from workers to global 248 * blocks LGMAN, TSMAN. These are run (sequentially) using 249 * the sub-op START_RECREQ_2. 250 */ nameDblqhProxy::Ss_START_RECREQ251 static const char* name() { return "START_RECREQ"; } 252 StartRecReq m_req; 253 Uint32 phaseToSend; 254 Uint32 restoreFragCompletedCount; 255 Uint32 undoDDCompletedCount; 256 Uint32 execREDOLogCompletedCount; 257 // pointers to START_RECREQ_2 for LGMAN, TSMAN 258 enum { m_req2cnt = 2 }; 259 struct { 260 Uint32 m_blockNo; 261 Uint32 m_ssId; 262 } m_req2[m_req2cnt]; Ss_START_RECREQDblqhProxy::Ss_START_RECREQ263 Ss_START_RECREQ() { 264 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendSTART_RECREQ; 265 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendSTART_RECCONF; 266 m_req2[0].m_blockNo = LGMAN; 267 m_req2[1].m_blockNo = TSMAN; 268 } 269 enum { poolSize = 1 }; poolDblqhProxy::Ss_START_RECREQ270 static SsPool<Ss_START_RECREQ>& pool(LocalProxy* proxy) { 271 return ((DblqhProxy*)proxy)->c_ss_START_RECREQ; 272 } 273 }; 274 SsPool<Ss_START_RECREQ> c_ss_START_RECREQ; 275 void execSTART_RECREQ(Signal*); 276 void sendSTART_RECREQ(Signal*, Uint32 ssId, SectionHandle*); 277 void execSTART_RECCONF(Signal*); 278 void execLOCAL_RECOVERY_COMP_REP(Signal*); 279 void sendSTART_RECCONF(Signal*, Uint32 ssId); 280 281 // GSN_START_RECREQ_2 [ sub-op, fictional gsn ] 282 struct Ss_START_RECREQ_2 : SsParallel { nameDblqhProxy::Ss_START_RECREQ_2283 static const char* name() { return "START_RECREQ_2"; } 284 struct Req { 285 enum { SignalLength = 2 }; 286 Uint32 lcpId; 287 Uint32 proxyBlockNo; 288 }; 289 // senderData is unnecessary as signal is unique per proxyBlockNo 290 struct Conf { 291 enum { SignalLength = 1 }; 292 Uint32 senderRef; 293 }; 294 Req m_req; 295 Conf m_conf; Ss_START_RECREQ_2DblqhProxy::Ss_START_RECREQ_2296 Ss_START_RECREQ_2() { 297 // reversed sendREQ/sendCONF 298 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendSTART_RECCONF_2; 299 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendSTART_RECREQ_2; 300 } 301 enum { poolSize = 2 }; poolDblqhProxy::Ss_START_RECREQ_2302 static SsPool<Ss_START_RECREQ_2>& pool(LocalProxy* proxy) { 303 return ((DblqhProxy*)proxy)->c_ss_START_RECREQ_2; 304 } 305 }; 306 SsPool<Ss_START_RECREQ_2> c_ss_START_RECREQ_2; getSsId(const Ss_START_RECREQ_2::Req * req)307 Uint32 getSsId(const Ss_START_RECREQ_2::Req* req) { 308 return SsIdBase | req->proxyBlockNo; 309 } getSsId(const Ss_START_RECREQ_2::Conf * conf)310 Uint32 getSsId(const Ss_START_RECREQ_2::Conf* conf) { 311 return SsIdBase | refToBlock(conf->senderRef); 312 } 313 void execSTART_RECREQ_2(Signal*); 314 void sendSTART_RECREQ_2(Signal*, Uint32 ssId); 315 void execSTART_RECCONF_2(Signal*); 316 void sendSTART_RECCONF_2(Signal*, Uint32 ssId, SectionHandle*); 317 318 // GSN_LQH_TRANSREQ 319 struct Ss_LQH_TRANSREQ : SsParallel { nameDblqhProxy::Ss_LQH_TRANSREQ320 static const char* name() { return "LQH_TRANSREQ"; } 321 /** 322 * Is this entry valid, or has it been made obsolete by 323 * a new LQH_TRANSREQ (i.e a new TC-failure) 324 */ 325 bool m_valid; 326 Uint32 m_maxInstanceId; 327 LqhTransReq m_req; 328 LqhTransConf m_conf; // latest conf Ss_LQH_TRANSREQDblqhProxy::Ss_LQH_TRANSREQ329 Ss_LQH_TRANSREQ() { 330 m_valid = true; 331 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendLQH_TRANSREQ; 332 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendLQH_TRANSCONF; 333 } 334 enum { poolSize = MAX_NDB_NODES }; poolDblqhProxy::Ss_LQH_TRANSREQ335 static SsPool<Ss_LQH_TRANSREQ>& pool(LocalProxy* proxy) { 336 return ((DblqhProxy*)proxy)->c_ss_LQH_TRANSREQ; 337 } 338 }; 339 SsPool<Ss_LQH_TRANSREQ> c_ss_LQH_TRANSREQ; 340 void execLQH_TRANSREQ(Signal*); 341 void sendLQH_TRANSREQ(Signal*, Uint32 ssId, SectionHandle*); 342 void execLQH_TRANSCONF(Signal*); 343 void sendLQH_TRANSCONF(Signal*, Uint32 ssId); 344 345 // GSN_EXEC_SR_1 [ fictional gsn ] 346 struct Ss_EXEC_SR_1 : SsParallel { 347 /* 348 * Handle EXEC_SRREQ and EXEC_SRCONF. These are broadcast 349 * signals (not REQ/CONF). EXEC_SR_1 receives one signal and 350 * sends it to its workers. EXEC_SR_2 waits for signal from 351 * all workers and broadcasts it to all nodes. These are 352 * required to handle mixed versions (non-mt, mt-lqh-1,2,4). 353 */ nameDblqhProxy::Ss_EXEC_SR_1354 static const char* name() { return "EXEC_SR_1"; } 355 struct Sig { 356 enum { SignalLength = 1 }; 357 Uint32 nodeId; 358 }; 359 GlobalSignalNumber m_gsn; 360 Sig m_sig; Ss_EXEC_SR_1DblqhProxy::Ss_EXEC_SR_1361 Ss_EXEC_SR_1() { 362 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendEXEC_SR_1; 363 m_sendCONF = (SsFUNCREP)0; 364 m_gsn = 0; 365 }; 366 enum { poolSize = 1 }; poolDblqhProxy::Ss_EXEC_SR_1367 static SsPool<Ss_EXEC_SR_1>& pool(LocalProxy* proxy) { 368 return ((DblqhProxy*)proxy)->c_ss_EXEC_SR_1; 369 } 370 }; 371 SsPool<Ss_EXEC_SR_1> c_ss_EXEC_SR_1; getSsId(const Ss_EXEC_SR_1::Sig * sig)372 Uint32 getSsId(const Ss_EXEC_SR_1::Sig* sig) { 373 return SsIdBase | refToNode(sig->nodeId); 374 }; 375 void execEXEC_SRREQ(Signal*); 376 void execEXEC_SRCONF(Signal*); 377 void execEXEC_SR_1(Signal*, GlobalSignalNumber gsn); 378 void sendEXEC_SR_1(Signal*, Uint32 ssId, SectionHandle*); 379 380 // GSN_EXEC_SR_2 [ fictional gsn ] 381 struct Ss_EXEC_SR_2 : SsParallel { nameDblqhProxy::Ss_EXEC_SR_2382 static const char* name() { return "EXEC_SR_2"; } 383 struct Sig { 384 enum { SignalLength = 1 + NdbNodeBitmask::Size }; 385 Uint32 nodeId; 386 Uint32 sr_nodes[NdbNodeBitmask::Size]; // local signal so ok to add 387 }; 388 GlobalSignalNumber m_gsn; 389 Uint32 m_sigcount; 390 Sig m_sig; // all signals must be identical Ss_EXEC_SR_2DblqhProxy::Ss_EXEC_SR_2391 Ss_EXEC_SR_2() { 392 // reversed roles 393 m_sendREQ = (SsFUNCREQ)0; 394 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendEXEC_SR_2; 395 m_gsn = 0; 396 m_sigcount = 0; 397 }; 398 enum { poolSize = 1 }; poolDblqhProxy::Ss_EXEC_SR_2399 static SsPool<Ss_EXEC_SR_2>& pool(LocalProxy* proxy) { 400 return ((DblqhProxy*)proxy)->c_ss_EXEC_SR_2; 401 } 402 }; 403 SsPool<Ss_EXEC_SR_2> c_ss_EXEC_SR_2; getSsId(const Ss_EXEC_SR_2::Sig * sig)404 Uint32 getSsId(const Ss_EXEC_SR_2::Sig* sig) { 405 return SsIdBase | refToNode(sig->nodeId); 406 }; 407 void execEXEC_SR_2(Signal*, GlobalSignalNumber gsn); 408 void sendEXEC_SR_2(Signal*, Uint32 ssId); 409 410 /** 411 * GSN_EXEC_FRAGREQ & GSN_EXEC_FRAGCONF needs to 412 * be passed via proxy for correct serialization 413 * wrt to GSN_EXEC_SRREQ & GSN_EXEC_SRCONF 414 */ 415 void execEXEC_FRAGREQ(Signal*); 416 void execEXEC_FRAGCONF(Signal*); 417 418 // GSN_DROP_FRAG_REQ 419 struct Ss_DROP_FRAG_REQ : SsParallel { 420 DropFragReq m_req; Ss_DROP_FRAG_REQDblqhProxy::Ss_DROP_FRAG_REQ421 Ss_DROP_FRAG_REQ() { 422 m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendDROP_FRAG_REQ; 423 m_sendCONF = (SsFUNCREP)&DblqhProxy::sendDROP_FRAG_CONF; 424 } 425 enum { poolSize = 1 }; poolDblqhProxy::Ss_DROP_FRAG_REQ426 static SsPool<Ss_DROP_FRAG_REQ>& pool(LocalProxy* proxy) { 427 return ((DblqhProxy*)proxy)->c_ss_DROP_FRAG_REQ; 428 } 429 }; 430 SsPool<Ss_DROP_FRAG_REQ> c_ss_DROP_FRAG_REQ; getSsId(const DropFragReq * req)431 Uint32 getSsId(const DropFragReq* req) { 432 return SsIdBase | (req->tableId ^ req->fragId); 433 } getSsId(const DropFragConf * conf)434 Uint32 getSsId(const DropFragConf* conf) { 435 return SsIdBase | (conf->tableId ^ conf->fragId); 436 } getSsId(const DropFragRef * ref)437 Uint32 getSsId(const DropFragRef* ref) { 438 return SsIdBase | (ref->tableId ^ ref->fragId); 439 } 440 void execDROP_FRAG_REQ(Signal*); 441 void sendDROP_FRAG_REQ(Signal*, Uint32 ssId, SectionHandle*); 442 void execDROP_FRAG_CONF(Signal*); 443 void execDROP_FRAG_REF(Signal*); 444 void sendDROP_FRAG_CONF(Signal*, Uint32 ssId); 445 446 // LCP handling 447 void execEMPTY_LCP_REQ(Signal*); 448 void execLCP_FRAG_ORD(Signal*); 449 void execLCP_FRAG_REP(Signal*); 450 void execEND_LCPCONF(Signal*); 451 void execLCP_COMPLETE_REP(Signal*); 452 453 struct LcpRecord { 454 enum { 455 L_IDLE = 0, 456 L_RUNNING = 1, 457 L_COMPLETING_1 = 2, 458 L_COMPLETING_2 = 3, 459 L_COMPLETING_3 = 4 460 } m_state; 461 Uint32 m_lcpId; 462 Uint32 m_keepGci; 463 Uint32 m_lcp_frag_ord_cnt; // No of LCP_FRAG_ORD received 464 Uint32 m_lcp_frag_rep_cnt; // No of LCP_FRAG_REP sent 465 Uint32 m_complete_outstanding; // Outstanding END_LCPREQ 466 NdbNodeBitmask m_empty_lcp_req;// Nodes waiting for EMPTY_LCP_CONF 467 LcpFragOrd m_last_lcp_frag_ord;// Last received LCP_FRAG_ORD 468 bool m_lastFragmentFlag; 469 LcpRecordDblqhProxy::LcpRecord470 LcpRecord(){ 471 m_state = L_IDLE; 472 m_lcpId = 0; 473 m_lcp_frag_ord_cnt = 0; 474 m_lcp_frag_rep_cnt = 0; 475 m_lastFragmentFlag = false; 476 }; 477 }; 478 LcpRecord c_lcpRecord; 479 Uint32 getNoOfOutstanding(const LcpRecord&) const; 480 void completeLCP_1(Signal* signal); 481 void completeLCP_2(Signal* signal); 482 void completeLCP_3(Signal* signal); 483 void sendLCP_COMPLETE_REP(Signal*); 484 485 void checkSendEMPTY_LCP_CONF_impl(Signal* signal); checkSendEMPTY_LCP_CONF(Signal * signal)486 void checkSendEMPTY_LCP_CONF(Signal* signal) 487 { 488 if (c_lcpRecord.m_empty_lcp_req.isclear()) 489 return; 490 checkSendEMPTY_LCP_CONF_impl(signal); 491 } 492 }; 493 494 495 #undef JAM_FILE_ID 496 497 #endif 498