[jboss-svn-commits] JBL Code SVN: r29464 - in labs/jbosstm/workspace/adinn/byteman/trunk: src/org/jboss/byteman/synchronization and 4 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Sep 25 06:25:45 EDT 2009
Author: adinn
Date: 2009-09-25 06:25:45 -0400 (Fri, 25 Sep 2009)
New Revision: 29464
Added:
labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/bugfixes/TestWaitAfterSignalWakeMustMeet.txt
labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/bugfixes/TestWaitAfterSignalWakeMustMeet.java
labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/TestWaitAfterSignalWakeMustMeetHelper.java
Modified:
labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java
labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Waiter.java
labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml
Log:
fixed bug in waiter code and added test for it
Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java 2009-09-25 10:19:11 UTC (rev 29463)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java 2009-09-25 10:25:45 UTC (rev 29464)
@@ -433,9 +433,12 @@
// do nothing
}
}
- // remove the association between the waiter and the wait map
- removeWaiter(waiter);
}
+
+ // remove the association between the waiter and the wait map
+ synchronized (waitMap) {
+ removeWaiter(identifier);
+ }
return true;
}
}
@@ -515,9 +518,11 @@
// do nothing
}
}
- // remove the association between the waiter and the wait map
- removeWaiter(waiter);
}
+ // remove the association between the waiter and the wait map
+ synchronized (waitMap) {
+ removeWaiter(identifier);
+ }
return true;
}
}
Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Waiter.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Waiter.java 2009-09-25 10:19:11 UTC (rev 29463)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Waiter.java 2009-09-25 10:25:45 UTC (rev 29464)
@@ -63,7 +63,7 @@
// if a signalKill was used then we have to throw an exception otherwise we just return
if (killed) {
- throw new ExecuteException("Waiter.waitFor waiting thread killed for " + waiterFor);
+ throw new ExecuteException("Waiter.waitFor : killed thread waiting for " + waiterFor);
}
}
@@ -126,4 +126,12 @@
*/
private boolean waiting;
+
+ /**
+ * getter for signalled flag
+ * @return signalled
+ */
+ public boolean isSignalled() {
+ return signalled;
+ }
}
Modified: labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml 2009-09-25 10:19:11 UTC (rev 29463)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml 2009-09-25 10:25:45 UTC (rev 29464)
@@ -322,6 +322,16 @@
<pathelement location="${junit.home}/${junit.jar}"/>
</classpath>
<jvmarg value="-javaagent:${byteman.home}/${byteman.jar}=script:${scripts.dir}/javaops/TestArithmetic.txt"/>
+ <!-- uncomment to dump generated code
+ <jvmarg value="-Dorg.jboss.byteman.dump.generated.classes"/>
+ <jvmarg value="-Dorg.jboss.byteman.dump.generated.classes.directory=dump"/>
+ -->
+ <!-- uncomment to enable debug
+ <jvmarg value="-Xdebug"/>
+ <jvmarg value="-Xnoagent"/>
+ <jvmarg value="-Djava.compiler=NONE"/>
+ <jvmarg value="-Xrunjdwp:transport=dt_socket,server=n,suspend=y,address=5005"/>
+ -->
<jvmarg value="-Dorg.jboss.byteman.compileToBytecode"/>
<test name="org.jboss.byteman.tests.javaops.TestArithmetic"/>
</junit>
@@ -404,8 +414,8 @@
<jvmarg value="-Xnoagent"/>
<jvmarg value="-Djava.compiler=NONE"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,server=n,suspend=y,address=5005"/>
+ -->
<test name="org.jboss.byteman.tests.javaops.TestArray"/>
- -->
</junit>
</target>
@@ -494,6 +504,27 @@
-->
<test name="org.jboss.byteman.tests.bugfixes.TestThrowAction"/>
</junit>
+ <junit fork="true" showoutput="true">
+ <classpath>
+ <pathelement location="${build.lib.dir}/byteman-tests.jar"/>
+ <pathelement location="${junit.home}/${junit.jar}"/>
+ </classpath>
+ <jvmarg value="-javaagent:${byteman.home}/${byteman.jar}=script:${scripts.dir}/bugfixes/TestWaitAfterSignalWakeMustMeet.txt"/>
+ <!-- uncomment for verbose byteman output
+ <jvmarg value="-Dorg.jboss.byteman.verbose"/>
+ -->
+ <!-- uncomment to dump generated code
+ <jvmarg value="-Dorg.jboss.byteman.dump.generated.classes"/>
+ <jvmarg value="-Dorg.jboss.byteman.dump.generated.classes.directory=dump"/>
+ -->
+ <!-- uncomment to enable debug
+ <jvmarg value="-Xdebug"/>
+ <jvmarg value="-Xnoagent"/>
+ <jvmarg value="-Djava.compiler=NONE"/>
+ <jvmarg value="-Xrunjdwp:transport=dt_socket,server=n,suspend=y,address=5005"/>
+ -->
+ <test name="org.jboss.byteman.tests.bugfixes.TestWaitAfterSignalWakeMustMeet"/>
+ </junit>
</target>
<target name="tests.bugfixes.compiled">
@@ -588,6 +619,28 @@
-->
<test name="org.jboss.byteman.tests.bugfixes.TestThrowAction"/>
</junit>
+ <junit fork="true" showoutput="true">
+ <classpath>
+ <pathelement location="${build.lib.dir}/byteman-tests.jar"/>
+ <pathelement location="${junit.home}/${junit.jar}"/>
+ </classpath>
+ <jvmarg value="-javaagent:${byteman.home}/${byteman.jar}=script:${scripts.dir}/bugfixes/TestWaitAfterSignalWakeMustMeet.txt"/>
+ <jvmarg value="-Dorg.jboss.byteman.compileToBytecode"/>
+ <!-- uncomment for verbose byteman output
+ <jvmarg value="-Dorg.jboss.byteman.verbose"/>
+ -->
+ <!-- uncomment to dump generated code
+ <jvmarg value="-Dorg.jboss.byteman.dump.generated.classes"/>
+ <jvmarg value="-Dorg.jboss.byteman.dump.generated.classes.directory=dump"/>
+ -->
+ <!-- uncomment to enable debug
+ <jvmarg value="-Xdebug"/>
+ <jvmarg value="-Xnoagent"/>
+ <jvmarg value="-Djava.compiler=NONE"/>
+ <jvmarg value="-Xrunjdwp:transport=dt_socket,server=n,suspend=y,address=5005"/>
+ -->
+ <test name="org.jboss.byteman.tests.bugfixes.TestWaitAfterSignalWakeMustMeet"/>
+ </junit>
</target>
Added: labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/bugfixes/TestWaitAfterSignalWakeMustMeet.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/bugfixes/TestWaitAfterSignalWakeMustMeet.txt (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/bugfixes/TestWaitAfterSignalWakeMustMeet.txt 2009-09-25 10:25:45 UTC (rev 29464)
@@ -0,0 +1,123 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# by the @authors tag. See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY 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 along with this software; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+#
+# @authors Andrew Dinn
+#
+# Test for BYTEMAN-38
+
+##############################################################################
+# when test is entered we need to set up a rendezvous
+
+RULE setup
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD test
+HELPER org.jboss.byteman.tests.helpers.TestWaitAfterSignalWakeMustMeetHelper
+IF TRUE
+DO createRendezvous("test", 2, true)
+ENDRULE
+
+
+##############################################################################
+# when ensureSignalWake is called we need to ensure that another thread has
+# called signalWake. our helper specialises signalWake to allow this to be
+# checked
+
+RULE ensureSignalWait
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD ensureSignalWake
+HELPER org.jboss.byteman.tests.helpers.TestWaitAfterSignalWakeMustMeetHelper
+IF TRUE
+DO ensureSignalWake()
+ENDRULE
+
+##############################################################################
+# when ensureWaitFor is called we need to ensure that another thread has
+# called waitFor. our helper specialises waitFor to allow this to be
+# checked
+
+RULE ensureWaitFor
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD ensureWaitFor
+HELPER org.jboss.byteman.tests.helpers.TestWaitAfterSignalWakeMustMeetHelper
+IF TRUE
+DO ensureWaitFor()
+ENDRULE
+
+##############################################################################
+# when triggerWaitFor is called we need to do a waitFor
+
+RULE triggerWaitFor
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD triggerWaitFor
+HELPER org.jboss.byteman.tests.helpers.TestWaitAfterSignalWakeMustMeetHelper
+BIND test : TestEmptySignature = $0
+IF TRUE
+DO test.log("waitFor"),
+ waitFor("test")
+ENDRULE
+
+##############################################################################
+# when triggerSignalWake is called we need to do a signalWake
+
+RULE triggerSignalWake
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD triggerSignalWake
+HELPER org.jboss.byteman.tests.helpers.TestWaitAfterSignalWakeMustMeetHelper
+BIND test : TestEmptySignature = $0
+IF TRUE
+DO test.log("signalWake"),
+ signalWake("test", true)
+ENDRULE
+
+##############################################################################
+# when triggerRendezvous is called we need to do a rendezvous
+
+RULE triggerRendezvous
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD triggerRendezvous
+HELPER org.jboss.byteman.tests.helpers.TestWaitAfterSignalWakeMustMeetHelper
+IF TRUE
+DO rendezvous("test")
+ENDRULE
+
+##############################################################################
+# when triggerTimeoutCheck is called we need to wait and, if we timeout
+# throw an Exception
+
+RULE triggerTimeoutCheck
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD triggerTimeoutCheck
+IF TRUE
+DO waitFor("timeout", 60 * 1000),
+ throw Exception("failed with timeout")
+ENDRULE
+
+##############################################################################
+# when triggerTimeoutCancel is called we need to call signalThrow to cause
+# a runtime exception in the main thread.
+
+RULE triggerTimeoutCancel
+CLASS TestWaitAfterSignalWakeMustMeet
+METHOD triggerTimeoutCancel
+IF TRUE
+DO signalThrow("timeout")
+ENDRULE
+
Added: labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/bugfixes/TestWaitAfterSignalWakeMustMeet.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/bugfixes/TestWaitAfterSignalWakeMustMeet.java (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/bugfixes/TestWaitAfterSignalWakeMustMeet.java 2009-09-25 10:25:45 UTC (rev 29464)
@@ -0,0 +1,121 @@
+package org.jboss.byteman.tests.bugfixes;
+
+import org.jboss.byteman.tests.Test;
+import org.jboss.byteman.rule.exception.ExecuteException;
+
+/**
+ * This test accompaniesBYTEMAN-38. The bug happens when the same key is used for two successive pairs of
+ * calls to builtin helper methods waitFor(key) and signalWake(key, true). When the first call to waitFor
+ * happens before the first call to signalWake then the cleanup under signalWake fails to remove the
+ * Waiter object associated with key. The next call to waitFor finds a waiter which has been signalled
+ * and returns immediately. The call to signalWake shoudl remove the waiter before returning.
+ */
+public class TestWaitAfterSignalWakeMustMeet extends Test
+{
+ public TestWaitAfterSignalWakeMustMeet() {
+ super(TestWaitAfterSignalWakeMustMeet.class.getCanonicalName());
+ }
+
+ public void test() throws Exception
+ {
+ Thread thread1 = new Thread() {
+ public void run()
+ {
+ runThread1();
+ }
+ };
+ Thread thread2 = new Thread() {
+ public void run()
+ {
+ runThread2();
+ }
+ };
+ thread1.start();
+ thread2.start();
+ try {
+ triggerTimeoutCheck();
+ } catch (ExecuteException e) {
+ log("caught execute exception");
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ checkOutput();
+ }
+
+ public void ensureSignalWake()
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void ensureWaitFor()
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void triggerWaitFor()
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void triggerRendezvous()
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void triggerSignalWake()
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void triggerTimeoutCheck() throws Exception
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void triggerTimeoutCancel()
+ {
+ // do nothing. this is just for the purpose of triggering
+ }
+
+ public void runThread1()
+ {
+ ensureSignalWake();
+ //System.out.println("thread1 : ensured signalWake sent");
+ triggerWaitFor();
+ //System.out.println("thread1 : triggered waitFor");
+ triggerRendezvous();
+ //System.out.println("thread1 : triggered rendezvous 1");
+ triggerWaitFor();
+ //System.out.println("thread1 : triggered waitFor");
+ triggerRendezvous();
+ //System.out.println("thread1 : triggered rendezvous 2");
+ }
+
+ public void runThread2()
+ {
+ triggerSignalWake();
+ //System.out.println("thread2 : triggered signalWake");
+ ensureWaitFor();
+ //System.out.println("thread2 : ensured waitFor");
+ triggerRendezvous();
+ //System.out.println("thread2 : triggered rendezvous 1");
+ ensureWaitFor();
+ //System.out.println("thread2 : ensured waitFor");
+ triggerSignalWake();
+ //System.out.println("thread2 : triggered signalWake");
+ triggerRendezvous();
+ //System.out.println("thread2 : triggered rendezvous 2");
+ triggerTimeoutCancel();
+ //System.out.println("thread2 : cancelled timeout");
+ }
+
+ @Override
+ public String getExpected() {
+ logExpected("signalWake");
+ logExpected("waitFor");
+ logExpected("waitFor");
+ logExpected("signalWake");
+ logExpected("caught execute exception");
+ return super.getExpected();
+ }
+}
Added: labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/TestWaitAfterSignalWakeMustMeetHelper.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/TestWaitAfterSignalWakeMustMeetHelper.java (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/TestWaitAfterSignalWakeMustMeetHelper.java 2009-09-25 10:25:45 UTC (rev 29464)
@@ -0,0 +1,87 @@
+package org.jboss.byteman.tests.helpers;
+
+import org.jboss.byteman.rule.helper.Helper;
+import org.jboss.byteman.rule.Rule;
+
+/**
+ */
+public class TestWaitAfterSignalWakeMustMeetHelper extends Helper
+{
+ protected TestWaitAfterSignalWakeMustMeetHelper(Rule rule) {
+ super(rule);
+ }
+
+ static boolean waitForCalled = false;
+ static boolean signalWakeCalled = false;
+ static Object lock = new Object();
+
+ public void waitFor(Object identifier, long timeout)
+ {
+ setWaitFor(); // there is a window here! we use a delay to close it
+ super.waitFor(identifier, timeout);
+ }
+
+ public boolean signalWake(Object identifier, boolean mustMeet)
+ {
+ setSignalWake(); // there is a window here! we use a delay to close it
+ return super.signalWake(identifier, mustMeet);
+ }
+
+ private void setWaitFor()
+ {
+ synchronized (lock) {
+ waitForCalled = true;
+ //System.out.println("waitForCalled <= true");
+ lock.notify();
+ }
+ }
+
+ private void setSignalWake()
+ {
+ synchronized (lock) {
+ signalWakeCalled = true;
+ //System.out.println("signalWakeCalled <= true");
+ lock.notify();
+ }
+ }
+
+ public void ensureWaitFor()
+ {
+ synchronized (lock) {
+ //System.out.println("*waitForCalled = " + waitForCalled);
+ while (!waitForCalled) {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ //System.out.println("**waitForCalled = " + waitForCalled);
+ }
+ //System.out.println("***waitForCalled = " + waitForCalled);
+ waitForCalled = false;
+ //System.out.println("****waitForCalled = " + waitForCalled);
+ }
+ // close the window -- maybe leaves a little air gap
+ delay(1000);
+ }
+
+ public void ensureSignalWake()
+ {
+ synchronized (lock) {
+ //System.out.println("*signalWakeCalled = " + signalWakeCalled);
+ while (!signalWakeCalled) {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ //System.out.println("**signalWakeCalled = " + signalWakeCalled);
+ }
+ //System.out.println("***signalWakeCalled = " + signalWakeCalled);
+ signalWakeCalled = false;
+ //System.out.println("****signalWakeCalled = " + signalWakeCalled);
+ }
+ // close the window -- maybe leaves a little air gap
+ delay(1000);
+ }
+}
More information about the jboss-svn-commits
mailing list