XAStateModel.cxx
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:8k
源码类别:

中间件编程

开发平台:

Java

  1. /*
  2.  * JBoss, Home of Professional Open Source
  3.  * Copyright 2009, Red Hat, Inc., and others contributors as indicated
  4.  * by the @authors tag. All rights reserved.
  5.  * See the copyright.txt in the distribution for a
  6.  * full listing of individual contributors.
  7.  * This copyrighted material is made available to anyone wishing to use,
  8.  * modify, copy, or redistribute it subject to the terms and conditions
  9.  * of the GNU Lesser General Public License, v. 2.1.
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT A
  11.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
  13.  * You should have received a copy of the GNU Lesser General Public License,
  14.  * v.2.1 along with this distribution; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16.  * MA  02110-1301, USA.
  17.  */
  18. #include "XAStateModel.h"
  19. #include "log4cxx/logger.h"
  20. log4cxx::LoggerPtr xasmlogger(log4cxx::Logger::getLogger("TxLogXASM"));
  21. static std::string flag_dbg_str;
  22. extern std::ostream& operator<<(std::ostream &os, const XID& xid);
  23. namespace atmibroker {
  24. namespace xa {
  25. XAStateModel::XAStateModel() : astate_(T0), bstate_(S0)
  26. {
  27. }
  28. // enable XA state model checks - can be disabled to improve performance overhead
  29. // provided XAResourceAdaptorImpl remembers when it goes into state Idle (via calls to xa_end).
  30. // XAResourceAdaptorImpl::xa_end is the only place where the current state is consulted
  31. //#define XASM
  32. int XAStateModel::transition(XID& xid, enum XAEVENT method, long flags, int rv)
  33. {
  34. LOG4CXX_TRACE(xasmlogger, "transition:ENTER xid="
  35. << xid.formatID << ':' << xid.gtrid_length << ':' << xid.bqual_length << ':' << xid.data
  36. << " rv=" << rv << " flags=" << std::hex << flags << show_flags(flags)
  37. << " method=" << method << " astate=" << astate_ << " bstate=" << bstate_);
  38. #ifdef XASM
  39. int rv1 = XA_OK, rv2;
  40. if ((method < XACALL_PREPARE ))
  41. rv1 =  atransition(&astate_,  method, flags, rv);
  42. rv2 =  btransition(&bstate_,  method, flags, rv);
  43. if (rv != XA_OK && rv != XA_RDONLY) {
  44. // output at DEBUG rather than WARN since maintaining a distributed view of XA state model
  45. // is problematic
  46. LOG4CXX_DEBUG(xasmlogger, (char*) "XA error xa_ method: " << method << " error: " << rv);
  47. }
  48. LOG4CXX_TRACE(xasmlogger, (char*) "transition: rv1=" << rv1 << " rv2=" << rv2);
  49. #endif
  50. return rv;
  51. }
  52. int XAStateModel::transition(int allowable[], int *initial_state, int next_state)
  53. {
  54. LOG4CXX_TRACE(xasmlogger, (char *) "transition:ENTER");
  55. int *as = allowable;
  56. while (*as != -1) {
  57. if (*initial_state == *as++) {
  58. *initial_state = next_state;
  59. return XA_OK;
  60. }
  61. }
  62. // output at DEBUG rather than WARN since maintaining a distributed view of XA state model
  63. // is problematic
  64. if (*initial_state == next_state)
  65. return XA_OK; // TODO when do we get called without a change in state (recovery is one such example)
  66. LOG4CXX_DEBUG(xasmlogger, (char*) "Unexpected XA transition 0x" << std::hex << *initial_state
  67. << " -> 0x" << std::hex << next_state);
  68. return XAER_PROTO;
  69. }
  70. int XAStateModel::btransition(int *ini_state, enum XAEVENT method, long flag, int rval)
  71. {
  72. LOG4CXX_TRACE(xasmlogger, (char *) "btransition:ENTER");
  73. int ct[] = {*ini_state, -1};
  74. // int s0t[] = {S0, -1};
  75. int s1t[] = {S1, -1};
  76. int s2t[] = {S2, -1};
  77. int s3t[] = {S3, -1};
  78. // int s4t[] = {S4, -1};
  79. int s5t[] = {S5, -1};
  80. int s02t[] = {S0, S2, -1};
  81. int s23t[] = {S2, S3, -1};
  82. int s235t[] = {S2, S3, S5, -1};
  83. int s234t[] = {S2, S3, S4, -1};
  84. int s345t[] = {S3, S4, S5, -1};
  85. int s02345t[] = {S0, S2, S3, S4, S5, -1};
  86. if (rval == XAER_RMFAIL) {
  87. return transition(ct, ini_state, R0);
  88. } else if (method == XACALL_START) {
  89. if (rval >= XA_RBBASE && rval <= XA_RBEND)
  90. return transition(s2t, ini_state, S4);
  91. else
  92. return transition(s02t, ini_state, S1);
  93. } else if (method == XACALL_END) {
  94. if (rval >= XA_RBBASE && rval <= XA_RBEND)
  95. return transition(s1t, ini_state, S4);
  96. else
  97. return transition(s1t, ini_state, S2);
  98. } else if (method == XACALL_PREPARE) {
  99. if (rval == XAER_RMERR)
  100. return transition(s2t, ini_state, S2);
  101. else if (rval == XA_RDONLY || (rval >= XA_RBBASE && rval <= XA_RBEND))
  102. return transition(s2t, ini_state, S0);
  103. else
  104. return transition(s2t, ini_state, S3);
  105. } else if (method == XACALL_COMMIT) {
  106. if (rval == XA_OK || rval == XAER_RMERR)
  107. return transition(s23t, ini_state, S0);
  108. else if (rval >= XA_RBBASE && rval <= XA_RBEND)
  109. return transition(s2t, ini_state, S0);
  110. else if (rval == XA_RETRY)
  111. return transition(s3t, ini_state, S3);
  112. else if (rval == XA_HEURHAZ || rval == XA_HEURCOM || rval == XA_HEURRB || XA_HEURMIX)
  113. return transition(s235t, ini_state, S5);
  114. else
  115. LOG4CXX_TRACE(xasmlogger, "xa_commit: no transition for rval " << rval);
  116. } else if (method == XACALL_ROLLBACK) {
  117. if (rval == XA_OK || rval == XAER_RMERR || (rval >= XA_RBBASE && rval <= XA_RBEND))
  118. return transition(s234t, ini_state, S0);
  119. else if (rval == XA_HEURHAZ || rval == XA_HEURCOM || rval == XA_HEURRB || XA_HEURMIX)
  120. return transition(s345t, ini_state, S5);
  121. else
  122. LOG4CXX_TRACE(xasmlogger, "xa_rollback: no transition for rval " << rval);
  123. } else if (method == XACALL_FORGET) {
  124. if (rval == XAER_RMERR)
  125. return transition(s5t, ini_state, S5);
  126. else
  127. return transition(s5t, ini_state, S0);
  128. } else if (method == XACALL_OPEN) {
  129. return transition(ct, ini_state, *ini_state);
  130. } else if (method == XACALL_RECOVER) {
  131. return transition(ct, ini_state, *ini_state);
  132. } else if (method == XACALL_CLOSE) {
  133. return transition(s02345t, ini_state, R0);
  134. } else {
  135. LOG4CXX_TRACE(xasmlogger, "Unexpected branch state call " << method);
  136. *ini_state = R0;
  137. return XAER_PROTO;
  138. }
  139. }
  140. int XAStateModel::atransition(int *ini_state, enum XAEVENT method, long flag, int rval)
  141. {
  142. LOG4CXX_TRACE(xasmlogger, (char *) "atransition:ENTER");
  143. int ct[] = {*ini_state, -1};
  144. int t0t[] = {T0, -1};
  145. int t1t[] = {T1, -1};
  146. int xxxt1t[] = {T0, T1, -1};
  147. int t2t[] = {T2, -1};
  148. int xxxt2t[] = {T0, T2, -1};
  149. int t12t[] = {T1, T2, -1};
  150. int t02t[] = {T0, T2, -1};
  151. if (rval == XAER_RMFAIL) {
  152. return transition(ct, ini_state, R0);
  153. } else if (method == XACALL_START) {
  154. if (flag & TMRESUME) {
  155. if (rval >= XA_RBBASE && rval <= XA_RBEND)
  156. return transition(t2t, ini_state, T0);
  157. else
  158. return transition(xxxt2t, ini_state, T1);
  159. } else {
  160. return transition(t0t, ini_state, T1);
  161. }
  162. } else if (method == XACALL_END) {
  163. if (flag & TMSUSPEND) {
  164. LOG4CXX_TRACE(xasmlogger, (char*) "transition: XACALL_END TMSUSPEND " << rval);
  165. if (rval >= XA_RBBASE && rval <= XA_RBEND)
  166. return transition(t1t, ini_state, T0);
  167. else
  168. return transition(xxxt1t, ini_state, T2);
  169. } else if (flag & TMSUCCESS) {
  170. return transition(t12t, ini_state, T0);
  171. } else if (flag & TMFAIL) {
  172. return transition(t12t, ini_state, T0);
  173. } else {
  174. LOG4CXX_TRACE(xasmlogger, "Unexpected association end call - no matching transition: flag " << flag);
  175. *ini_state = R0;
  176. return XAER_PROTO;
  177. }
  178. } else if (method == XACALL_OPEN) {
  179. return transition(ct, ini_state, *ini_state);
  180. } else if (method == XACALL_RECOVER) {
  181. return transition(ct, ini_state, *ini_state);
  182. } else if (method == XACALL_CLOSE) {
  183. return transition(t02t, ini_state, R0);
  184. } else {
  185. LOG4CXX_TRACE(xasmlogger, "Unexpected association state call " << method);
  186. *ini_state = R0;
  187. return XAER_PROTO;
  188. }
  189. }
  190. std::string XAStateModel::show_flags(long flags)
  191. {
  192. flag_dbg_str = (char *) " (";
  193. if (flags & TMASYNC)
  194. flag_dbg_str += (char *) "TMASYNC|";
  195. if (flags & TMONEPHASE)
  196. flag_dbg_str += (char *) "TMONEPHASE|";
  197. if (flags & TMFAIL)
  198. flag_dbg_str += (char *) "TMFAIL|";
  199. if (flags & TMNOWAIT)
  200. flag_dbg_str += (char *) "TMNOWAIT|";
  201. if (flags & TMRESUME)
  202. flag_dbg_str += (char *) "TMRESUME|";
  203. if (flags & TMSUCCESS)
  204. flag_dbg_str += (char *) "TMSUCCESS|";
  205. if (flags & TMSUSPEND)
  206. flag_dbg_str += (char *) "TMSUSPEND|";
  207. if (flags & TMSTARTRSCAN)
  208. flag_dbg_str += (char *) "TMSTARTRSCAN|";
  209. if (flags & TMENDRSCAN)
  210. flag_dbg_str += (char *) "TMENDRSCAN|";
  211. if (flags & TMMULTIPLE)
  212. flag_dbg_str += (char *) "TMMULTIPLE|";
  213. if (flags & TMJOIN)
  214. flag_dbg_str += (char *) "TMJOIN|";
  215. if (flags & TMMIGRATE)
  216. flag_dbg_str += (char *) "TMMIGRATE|";
  217. flag_dbg_str += ')';
  218. return flag_dbg_str; //XX.c_str;
  219. }
  220. } // namespace xa {
  221. }   // namespace atmibroker {