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

中间件编程

开发平台:

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 "xa.h"
  19. #include "testrm.h"
  20. /*#include <userlogc.h>*/
  21. #include <stdlib.h>
  22. #include "ace/OS_NS_unistd.h"
  23. #include "ace/OS_NS_time.h"
  24. #include "ace/OS.h"
  25. static long counter = 0;
  26. static fault_t *faults = 0;
  27. struct xid_array {
  28. int count;
  29. int cursor;
  30. XID xids[10];
  31. };
  32. static XID gen_xid(long id, long sid, XID &gid)
  33. {
  34. XID xid = {gid.formatID, gid.gtrid_length};
  35. int i;
  36. for (i = 0; i < gid.gtrid_length; i++)
  37. xid.data[i] = gid.data[i];
  38. ACE_Time_Value now = ACE_OS::gettimeofday();
  39. // the first long in the XID data must contain the RM id
  40. (void) sprintf(xid.data + i, "%ld:%ld:%ld:%ld:%ld", id, sid, ++counter, now.sec(), now.usec());
  41. xid.bqual_length = strlen(xid.data + i);
  42. return xid;
  43. }
  44. static fault_t *last_fault() {
  45. fault_t *last;
  46. for (last = faults; last; last = last->next) {
  47. if (!last->next)
  48. return last;
  49. }
  50. return 0;
  51. }
  52. int dummy_rm_del_fault(int id)
  53. {
  54. fault_t *curr, *prev = 0;
  55. /*printf("dummy_rm: del_fault: %d", id);*/
  56. for (curr = faults; curr; prev = curr, curr = curr->next) {
  57. if (curr->id == id) {
  58. if (prev == NULL)
  59. faults = curr->next;
  60. else
  61. prev->next = curr->next;
  62. if (curr->rmstate != NULL)
  63. free(curr->rmstate);
  64. free(curr);
  65. return 0;
  66. }
  67. }
  68. return -1;
  69. }
  70. int dummy_rm_add_fault(fault_t *fault)
  71. {
  72. fault_t *last;
  73. /*printf("dummy_rm: del_fault:");*/
  74. if (fault == 0)
  75. return 1;
  76. last = last_fault();
  77. fault->next = 0;
  78. fault->orig = fault;
  79. fault->orig->res = 0;
  80. fault->orig->res2 = 0;
  81. if (fault->xf == F_ADD_XIDS) {
  82. int i;
  83. long larg = *((long*) fault->arg);
  84. struct xid_array *xids;
  85. XID gid = {1L, 1L, 0L};
  86. if (larg >= 10 || larg <= 0)
  87. return 1;
  88. xids = (struct xid_array *) calloc(1, sizeof(struct xid_array));
  89. fault->rmstate = xids;
  90. xids->cursor = 0;
  91. xids->count = larg;
  92. for (i = 0; i < xids->count; i++) {
  93. XID xid = gen_xid(fault->rmid, 0L, gid);
  94. memcpy(&(xids->xids[i]), &xid, sizeof (XID));
  95. }
  96. }
  97. if (last == 0) {
  98. faults = (fault_t *) calloc(1, sizeof(fault_t));
  99. fault->id = 0;
  100. *faults = *fault; // alternatively use the callers fault_t
  101. } else {
  102. last->next = (fault_t *) calloc(1, sizeof(fault_t));
  103. fault->id = last->id + 1;
  104. *(last->next) = *fault; // alternatively use the callers fault_t
  105. }
  106. return 0;
  107. }
  108. static int apply_faults(XID *xid, enum XA_OP op, int rmid)
  109. {
  110. fault_t *f;
  111. long *larg;
  112. /*printf("dummy_rm: apply_faults: op=%d rmid=%d", op, rmid);*/
  113. for (f = faults; f; f = f->next) {
  114. if (f->rmid == rmid && f->op == op) {
  115. /*printf("dummy_rm: applying fault to op %d rc %dn", op, f->rc);*/
  116. switch (f->xf) {
  117. default:
  118. break;
  119. case F_HALT:
  120. /* generate a SEGV fault */
  121. f->arg = 0;
  122. *((char *) f->arg) = 0;
  123. break;
  124. case F_DELAY:
  125. larg = (long*) f->arg;
  126. (void) ACE_OS::sleep(*larg);
  127. break;
  128. }
  129. return f->rc;
  130. }
  131. }
  132. return XA_OK;
  133. }
  134. static int open(char *a, int rmid, long l) {
  135. return apply_faults(NULL, O_XA_OPEN, rmid);
  136. }
  137. static int close(char *a, int rmid, long l) {
  138. return apply_faults(NULL, O_XA_CLOSE, rmid);
  139. }
  140. static int start(XID *x, int rmid, long l) {
  141. return apply_faults(x, O_XA_START, rmid);
  142. }
  143. static int end(XID *x, int rmid, long l) {
  144. return apply_faults(x, O_XA_END, rmid);
  145. }
  146. static int prepare(XID *x, int rmid, long l) {
  147. return apply_faults(x, O_XA_PREPARE, rmid);
  148. }
  149. // remove xid from any fault specifications used to support recovery testing
  150. static void end_check(XID *xid, int rmid) {
  151. fault_t *f;
  152. // TODO move this into apply_faults (ie generalise apply_faults)
  153. for (f = faults; f; f = f->next) {
  154. if (f->rmid == rmid && f->op == O_XA_RECOVER && f->xf == F_ADD_XIDS) {
  155. struct xid_array *xids = (struct xid_array *) f->rmstate;
  156. int i;
  157. for (i = 0; i < xids->count; i++) {
  158. if (memcmp(xid, &(xids->xids[i]), sizeof (XID)) == 0) { // bytewise compare
  159. for (i = i + 1; i < xids->count; i++)
  160. memcpy(&(xids->xids[i - 1]), &(xids->xids[i]), sizeof (XID));
  161. xids->count -= 1;
  162. // f->orig->res = xids->count;
  163. f->orig->res += 1;
  164. }
  165. }
  166. }
  167. }
  168. }
  169. static int commit(XID *x, int rmid, long l) {
  170. int rv = apply_faults(x, O_XA_COMMIT, rmid);
  171. end_check(x, rmid);
  172. return rv;
  173. }
  174. static int rollback(XID *x, int rmid, long l) {
  175. int rv = apply_faults(x, O_XA_ROLLBACK, rmid);
  176. end_check(x, rmid);
  177. return rv;
  178. }
  179. static int recover(XID *xid, long l1, int rmid, long flags) {
  180. fault_t *f;
  181. int rv = apply_faults(NULL, O_XA_RECOVER, rmid);
  182. for (f = faults; f; f = f->next) {
  183. if (f->rmid == rmid && f->op == O_XA_RECOVER && f->xf == F_ADD_XIDS) {
  184. struct xid_array *xids = (struct xid_array *) f->rmstate;
  185. int i;
  186. // note a recovery scan than spans multiple calls must be done in the same thread
  187. // - we don't check for this since this is only a dummy RM for testing particular
  188. // behaviour. Likewise we don't validate the TMNOFLAGS flag
  189. if ((xids == NULL && l1 > 0) || l1 < 0)
  190. return XAER_INVAL;
  191. if (flags & TMSTARTRSCAN)
  192. xids->cursor = 0;
  193. for (i = 0; i < l1 && xids->cursor <= xids->count; xids->cursor++, i++)
  194. xid[i] = xids->xids[xids->cursor];
  195. if (flags & TMENDRSCAN)
  196. xids->cursor = 0;
  197. // record the number of recovered XIDs in res and the number needing recovery in res2
  198. f->orig->res = 0;
  199. f->orig->res2 = xids->count;
  200. return i > 0 ? i - 1 : i;
  201. }
  202. }
  203. return rv;
  204. }
  205. static int forget(XID *x, int rmid, long l) {
  206. int rv =  apply_faults(x, O_XA_FORGET, rmid);
  207. end_check(x, rmid);
  208. return rv;
  209. }
  210. static int complete(int *ip1, int *ip2, int rmid, long l) {
  211. return apply_faults(NULL, O_XA_COMPLETE, rmid);
  212. }
  213. struct xa_switch_t testxasw = {
  214. "DummyRM", 0L, 0,
  215. open, close,
  216. start, end, rollback, prepare, commit,
  217. recover,
  218. forget,
  219. complete
  220. };