[jboss-svn-commits] JBL Code SVN: r19345 - in labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats: jts and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Mar 31 11:55:02 EDT 2008
Author: adinn
Date: 2008-03-31 11:55:02 -0400 (Mon, 31 Mar 2008)
New Revision: 19345
Added:
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/PseudoControlWrapper.java
Modified:
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/OTSManager.java
Log:
fixes for JBTM-352
Added: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/PseudoControlWrapper.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/PseudoControlWrapper.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/PseudoControlWrapper.java 2008-03-31 15:55:02 UTC (rev 19345)
@@ -0,0 +1,210 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ */
+
+package com.arjuna.ats.internal.jts;
+
+import org.omg.CosTransactions.*;
+import org.omg.CORBA.SystemException;
+
+import com.arjuna.ArjunaOTS.*;
+
+import com.arjuna.ats.internal.jts.orbspecific.ControlImple;
+import com.arjuna.ats.internal.jts.utils.Helper;
+import com.arjuna.ats.arjuna.common.Uid;
+
+/**
+ * a wrapper used to wrap a ControlImple or a Control when attempting to remove it from the TransactionReaper
+ * transactions list. this wrapper ensures that hashcode and equals calls compare correctly while performing
+ * as few remote invocations as possible to do the comparison.
+ */
+public class PseudoControlWrapper
+{
+ // public API
+
+ /**
+ * wrap a Control in a wrapper which can be used to test for equality against ControlWrapper instances
+ * n.b. the Control must have been determined to be a non-local control by the caller
+ *
+ * @param control
+ */
+ public PseudoControlWrapper(Control control)
+ {
+ _coordinator = null; // for non-local control -- only compute when needed
+ _control = control;
+ _uid = null; // for non-local control -- only compute when needed
+ _local = null;
+ _hashCode = computeHashCode();
+ }
+
+ /**
+ * wrap a ControlImple in a wrapper which can be used to test for equality against ControlWrapper instances
+ *
+ * @param controlImple
+ */
+ public PseudoControlWrapper(ControlImple controlImple)
+ {
+ _coordinator = null; // for non-local control -- only compute when needed
+ _control = null;
+ _uid = null; // for non-local control -- only compute when needed
+ _local = controlImple;
+ _hashCode = computeHashCode();
+ }
+
+ /**
+ * this returns the same hashcode as ControlWrapper for a given Control or ControlImple
+ *
+ * @return
+ */
+ public int hashCode()
+ {
+ return _hashCode;
+ }
+
+ /**
+ * Test whether this PseudoControlWrapper wraps the same Control as a ControlWrapper
+ *
+ * The equality rules differ depending upon whether this wraps a local or remote Control
+ *
+ * if the wrapped control is local then the local uid can be compared against the uid cached in the ControlWrapper
+ *
+ * if the wrapped control is non-local then the test depends upon whether the ControlWrapper wraps a local
+ * or remote control. in the former case a uid comparison can be used. in the latter case the coordinators of
+ * the two controls must be obtained and a call to coord.is_same_transaction(othercoord) must be used.
+ *
+ * @caveats this comparison is only defined against instances of ControlWrapper because this class should only be
+ * used to wrap a control for comparison against an entry in the TransactionReaper's list of controls and should
+ * only compare equal to an entry which is a ControlWrapper for the same Control. as such it breaks all the
+ * rules for an equals implementation and should not be expected to work anywhere else.
+ *
+ *
+ */
+ public boolean equals(Object o)
+ {
+ if (o instanceof ControlWrapper) {
+ ControlWrapper wrapper = (ControlWrapper)o;
+
+ if (_local != null) {
+ // the other guys uid will already have been computed so just do a uid -- uid comparison
+ return _local.get_uid().equals(wrapper.get_uid());
+ } else if (_control == null) {
+ return false;
+ } else if (wrapper.isLocal()) {
+ // the other control is local so a UID comparison must be ok
+ try
+ {
+ // make sure we have our uid
+ if (_uid == null) {
+ _uid = computeUid();
+ }
+ return _uid.equals(wrapper.get_uid());
+ } catch (Exception e) {
+ return false;
+ }
+ } else {
+ /*
+ * Trying to compare two non-local controls -- assuming the previous implementation was correct we
+ * need to do a full comparison of this control's coordinator against the wrapper control's coordinator
+ * TODO why can't we just get the two UIDs and compare them?
+ */
+ try {
+ // make sure we have our coordinator
+ if (_coordinator == null) {
+ _coordinator = computeCoordinator();
+ }
+ return _coordinator.is_same_transaction(wrapper.get_coordinator());
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * fetch the coordinator for the wrapped non-local control
+ * @return the remote coordinator
+ * @throws Exception if the coordinator cannot be obtained e.g. because the control is no longer valid
+ */
+ private Coordinator computeCoordinator()
+ throws Exception
+ {
+ return _control.get_coordinator();
+
+ }
+
+ /**
+ * fetc the uid for the wrapped non-local control
+ * @return the uid
+ * @throws Exception if the coordinator cannot be obtained e.g. because the control is no longer valid
+ */
+ private Uid computeUid()
+ throws Exception
+ {
+ if (_coordinator == null) {
+ _coordinator = computeCoordinator();
+ }
+
+ UidCoordinator uidCoord = Helper.getUidCoordinator(_coordinator);
+
+ return Helper.getUid(uidCoord);
+ }
+
+ /**
+ * compute the hashcode for the wrapped local or remote control using the same algorithm as ControlWrapper
+ * @return the hashcode
+ */
+ private int computeHashCode()
+ {
+ try {
+ if (_local != null) {
+ return _local.getImplHandle().hash_transaction();
+ } else if (_control != null) {
+ Coordinator coord = _control.get_coordinator();
+
+ return coord.hash_transaction();
+ }
+ } catch (Exception e) {
+ }
+ return -1;
+ }
+
+ /**
+ * the wrapped local control or null if the control is non-local
+ */
+ private ControlImple _local;
+ /**
+ * the wrapped non-local control or null if the control is local
+ */
+ private Control _control;
+ /**
+ * coordinator for the wrapped non-local control computed lazily as needed
+ */
+ private Coordinator _coordinator;
+ /**
+ * uid for the wrapped non-local control computed lazily as needed
+ */
+ private Uid _uid;
+ /**
+ * hashcode for the wrapped control
+ */
+ private int _hashCode;
+}
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/OTSManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/OTSManager.java 2008-03-31 15:15:06 UTC (rev 19344)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/OTSManager.java 2008-03-31 15:55:02 UTC (rev 19345)
@@ -48,6 +48,7 @@
import com.arjuna.ats.internal.jts.orbspecific.ControlImple;
import com.arjuna.ats.internal.jts.orbspecific.TransactionFactoryImple;
import com.arjuna.ats.internal.jts.ORBManager;
+import com.arjuna.ats.internal.jts.PseudoControlWrapper;
import com.arjuna.ats.internal.jts.utils.Helper;
import org.omg.CosTransactions.*;
@@ -163,7 +164,9 @@
com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "OTS::destroyControl - removing control from reaper.");
}
- TransactionReaper.transactionReaper().remove(control.get_uid());
+ // wrap the control so it gets compared against reaper list entries using the correct test
+ PseudoControlWrapper wrapper = new PseudoControlWrapper(control);
+ TransactionReaper.transactionReaper().remove(wrapper);
}
}
catch (Exception e)
@@ -239,9 +242,12 @@
{
try
{
- if (coord.is_top_level_transaction())
- TransactionReaper.transactionReaper().remove(control);
- }
+ if (coord.is_top_level_transaction()) {
+ // wrap the control so it gets compared against reaper list entries using the correct test
+ PseudoControlWrapper wrapper = new PseudoControlWrapper(control);
+ TransactionReaper.transactionReaper().remove(wrapper);
+ }
+ }
catch (Exception e)
{
}
More information about the jboss-svn-commits
mailing list