[jboss-svn-commits] JBL Code SVN: r29620 - in labs/jbosstm/workspace/adinn/byteman/trunk: src/org/jboss/byteman/rule/helper and 6 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Oct 15 09:22:00 EDT 2009


Author: adinn
Date: 2009-10-15 09:21:58 -0400 (Thu, 15 Oct 2009)
New Revision: 29620

Added:
   labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/misc/
   labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/misc/TestRecursiveTriggers.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/misc/
   labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/misc/TestRecursiveTriggers.java
Modified:
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/Rule.java
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java
   labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml
   labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/Default.java
Log:
disabled triggering during rule type check and compilation. Also provided helper builtin setTriggering(boolean) which can be used to enableor disable triggering for subsequent expressions evbaluated during execution of the current rule -- partially fixes BYTEMAN-50 but still needs doc and guards againts recursive triggering in other parts of the byteman code

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/Rule.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/Rule.java	2009-10-15 13:06:45 UTC (rev 29619)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/Rule.java	2009-10-15 13:21:58 UTC (rev 29620)
@@ -261,7 +261,7 @@
     public Type getReturnType()
     {
         return returnType;
-    }
+    }                                                                                     
 
     /**
      * get the class loader of the target class for the rule
@@ -336,6 +336,51 @@
     }
 
     /**
+     * disable triggering of rules inside the current thread
+     * @return true if triggering was previously enabled and false if it was already disabled
+     */
+    public boolean disableTriggers()
+    {
+        Rule enabledRule = recursionGuard.get();
+        if (enabledRule == null) {
+            recursionGuard.set(this);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * enable triggering of rules inside the current thread
+     * @return true if triggering was previously enabled and false if it was already disabled
+     */
+    public boolean enableTriggers()
+    {
+        Rule enabledRule = recursionGuard.get();
+        if (enabledRule == null) {
+            return true;
+        } else {
+            recursionGuard.remove();
+            return true;
+        }
+    }
+
+    /**
+     * check if triggering of rules is enabled inside the current thread
+     * @return true if triggering is enabled and false if it is disabled
+     */
+    public boolean isTriggeringEnabled()
+    {
+        Rule enabledRule = recursionGuard.get();
+        if (enabledRule == null) {
+            return true;
+        } else {
+            recursionGuard.remove();
+            return true;
+        }
+    }
+
+    /**
      * typecheck and then compile this rule unless either action has been tried before
      * @return true if the rule successfully type checks and then compiles under this call or a previous
      * call or false if either operation has previously failed or fails under this call.
@@ -347,6 +392,9 @@
         }
 
         if (!checked) {
+            // ensure we don't trigger any code inside the type check or compile
+            // n.b. we may still allow recursive triggering while executing
+            boolean triggerEnabled = disableTriggers();
             String detail = "";
             try {
                 typeCheck();
@@ -368,6 +416,11 @@
                 ce.printStackTrace(writer);
                 detail = stringWriter.toString();
                 System.out.println(detail);
+            } finally {
+                // be sure to return the status quo
+                if (triggerEnabled) {
+                    enableTriggers();
+                }
             }
 
             ruleScript.recordCompile(triggerClass, loader, !checkFailed, detail);
@@ -493,6 +546,11 @@
      */
     public static void execute(String key, Object recipient, Object[] args) throws ExecuteException
     {
+        Rule inTypeCheckCompile = recursionGuard.get();
+        if (inTypeCheckCompile != null) {
+            // we don't trigger code while we are doing ruel type checking or compilation
+            return;
+        }
         Rule rule = ruleKeyMap.get(key);
         if (Transformer.isVerbose()) {
             System.out.println("Rule.execute called for " + key);
@@ -563,6 +621,9 @@
             } catch (Throwable throwable) {
                 System.out.println(getName() + " : " + throwable);
                 throw new ExecuteException(getName() + "  : caught " + throwable, throwable);
+            } finally {
+                // restore the status quo -- we must have been enabled if we got to this method
+                enableTriggers();
             }
         }
     }
@@ -687,4 +748,5 @@
     }
     
     private static boolean debugParse = (System.getProperty("org.jboss.byteman.rule.debug") != null ? true : false);
+    private static ThreadLocal<Rule> recursionGuard = new ThreadLocal<Rule>();
 }

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-10-15 13:06:45 UTC (rev 29619)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java	2009-10-15 13:21:58 UTC (rev 29620)
@@ -907,6 +907,20 @@
     }
 
     /**
+     * enable or disable recursive triggering of rules by subsequent operations performed during binding,
+     * testing or firing of the current rule in the current thread.
+     * @param enabled true if triggering should be enabled or false if it should be disabled
+     */
+    public void setTriggering(boolean enabled)
+    {
+        if (enabled) {
+            rule.enableTriggers();
+        } else {
+            rule.disableTriggers();
+        }
+    }
+
+    /**
      * return a unique name for the trigger point associated with this rule. n.b. a single rule may
      * give rise to more than one trigger point if the rule applies to several methods with the same
      * name or to several classes with the same (package unqualified) name, or even to several

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml	2009-10-15 13:06:45 UTC (rev 29619)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/build.xml	2009-10-15 13:21:58 UTC (rev 29620)
@@ -72,7 +72,7 @@
        <delete dir="${build.dir}"/>
     </target>
 
-    <target name="tests" depends="jar, tests.location, tests.location.compiled, tests.javaops, tests.javaops.compiled, tests.bugfixes, tests.bugfixes.compiled"/>
+    <target name="tests" depends="jar, tests.location, tests.location.compiled, tests.javaops, tests.javaops.compiled, tests.misc, tests.misc.compiled, tests.bugfixes, tests.bugfixes.compiled"/>
 
     <target name="tests.location">
         <junit fork="true" showoutput="true">
@@ -419,6 +419,41 @@
         </junit>
     </target>
 
+    <target name="tests.misc">
+        <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}/misc/TestRecursiveTriggers.txt"/>
+            <!--
+            <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.misc.TestRecursiveTriggers"/>
+        </junit>
+    </target>
+
+    <target name="tests.misc.compiled">
+        <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}/misc/TestRecursiveTriggers.txt"/>
+            <jvmarg value="-Dorg.jboss.byteman.compileToBytecode"/>
+            <!--
+            <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.misc.TestRecursiveTriggers"/>
+        </junit>
+    </target>
+
     <target name="tests.bugfixes">
         <junit fork="true" showoutput="true">
           <classpath>

Copied: labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/misc/TestRecursiveTriggers.txt (from rev 29491, labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/javaops/TestArithmetic.txt)
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/misc/TestRecursiveTriggers.txt	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/dd/scripts/misc/TestRecursiveTriggers.txt	2009-10-15 13:21:58 UTC (rev 29620)
@@ -0,0 +1,78 @@
+##############################################################################
+# 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
+#
+
+##############################################################################
+#
+# log a message to indicate that triggerMethod1 was called and fired the rule
+
+RULE log potentially recursively triggered method
+CLASS org.jboss.byteman.tests.misc.TestRecursiveTriggers
+METHOD triggerMethod1(int)
+HELPER org.jboss.byteman.tests.helpers.Default
+AT ENTRY
+BIND test = $0,
+     count = $1
+IF TRUE
+DO test.log("triggerMethod1 : triggered with " + count)
+ENDRULE
+
+##############################################################################
+#
+# log a message to indicate that triggerMethod2 was called and call
+# triggerMethod1 with recursive triggering enabled (the default)
+
+RULE test recursive trigger enabled
+CLASS org.jboss.byteman.tests.misc.TestRecursiveTriggers
+METHOD triggerMethod2()
+HELPER org.jboss.byteman.tests.helpers.Default
+AT ENTRY
+BIND test : TestRecursiveTriggers = $0
+IF TRUE
+DO test.log("triggerMethod2 : triggered"),
+   test.triggerMethod1(2)
+ENDRULE
+
+##############################################################################
+#
+# log a message to indicate that triggerMethod2 was called and call
+# triggerMethod1 with recursive triggering disabled and then again with
+# triggering enabled
+
+
+RULE test recursive trigger disabled then enabled
+CLASS org.jboss.byteman.tests.misc.TestRecursiveTriggers
+METHOD triggerMethod3()
+HELPER org.jboss.byteman.tests.helpers.Default
+AT ENTRY
+BIND test : TestRecursiveTriggers = $0
+IF TRUE
+DO test.log("triggerMethod3 : triggered"),
+   setTriggering(false),
+   test.triggerMethod1(3),
+   setTriggering(true),
+   test.triggerMethod1(4)
+ENDRULE
+
+
+

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/Default.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/Default.java	2009-10-15 13:06:45 UTC (rev 29619)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/helpers/Default.java	2009-10-15 13:21:58 UTC (rev 29620)
@@ -24,12 +24,19 @@
 package org.jboss.byteman.tests.helpers;
 
 import org.jboss.byteman.tests.Test;
+import org.jboss.byteman.rule.helper.Helper;
+import org.jboss.byteman.rule.Rule;
 
 /**
  * default helper used in byteman unit tests providing simple logging capability
  */
-public class Default
+public class Default extends Helper
 {
+    public Default(Rule rule)
+    {
+        super(rule);
+    }
+    
     public void log(String message)
     {
         System.out.println(message);

Copied: labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/misc/TestRecursiveTriggers.java (from rev 29491, labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/javaops/TestArithmetic.java)
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/misc/TestRecursiveTriggers.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/tests/src/org/jboss/byteman/tests/misc/TestRecursiveTriggers.java	2009-10-15 13:21:58 UTC (rev 29620)
@@ -0,0 +1,109 @@
+/*
+* 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
+*/
+package org.jboss.byteman.tests.misc;
+
+import org.jboss.byteman.tests.Test;
+
+/**
+ * Test to ensure arithmetic operations compute as expected
+ */
+public class TestRecursiveTriggers extends Test
+{
+    public TestRecursiveTriggers()
+    {
+        super(TestRecursiveTriggers.class.getCanonicalName());
+    }
+
+    public void test()
+    {
+        try {
+            log("calling TestRecursiveTriggers.triggerMethod1(1)");
+            triggerMethod1(1);
+            log("called TestRecursiveTriggers.triggerMethod1(1)");
+
+            log("calling TestRecursiveTriggers.triggerMethod2()");
+            triggerMethod2();
+            log("called TestRecursiveTriggers.triggerMethod2()");
+
+            log("calling TestRecursiveTriggers.triggerMethod3()");
+            triggerMethod3();
+            log("called TestRecursiveTriggers.triggerMethod3()");
+
+            log("calling TestRecursiveTriggers.triggerMethod2()");
+            triggerMethod2();
+            log("called TestRecursiveTriggers.triggerMethod2()");
+        } catch (Exception e) {
+            log(e);
+        }
+
+        checkOutput(true);
+    }
+
+    public void triggerMethod1(int i)
+    {
+        log("inside TestRecursiveTriggers.triggerMethod1(" + i + ")");
+    }
+
+    public void triggerMethod2()
+    {
+        log("inside TestRecursiveTriggers.triggerMethod2()");
+    }
+
+    public void triggerMethod3()
+    {
+        log("inside TestRecursiveTriggers.triggerMethod3()");
+    }
+
+    @Override
+    public String getExpected() {
+        logExpected("calling TestRecursiveTriggers.triggerMethod1(1)");
+        logExpected("triggerMethod1 : triggered with 1");
+        logExpected("inside TestRecursiveTriggers.triggerMethod1(1)");
+        logExpected("called TestRecursiveTriggers.triggerMethod1(1)");
+
+        logExpected("calling TestRecursiveTriggers.triggerMethod2()");
+        logExpected("triggerMethod2 : triggered");
+        logExpected("triggerMethod1 : triggered with 2");
+        logExpected("inside TestRecursiveTriggers.triggerMethod1(2)");
+        logExpected("inside TestRecursiveTriggers.triggerMethod2()");
+        logExpected("called TestRecursiveTriggers.triggerMethod2()");
+
+        logExpected("calling TestRecursiveTriggers.triggerMethod3()");
+        logExpected("triggerMethod3 : triggered");
+        logExpected("inside TestRecursiveTriggers.triggerMethod1(3)");
+        logExpected("triggerMethod1 : triggered with 4");
+        logExpected("inside TestRecursiveTriggers.triggerMethod1(4)");
+        logExpected("inside TestRecursiveTriggers.triggerMethod3()");
+        logExpected("called TestRecursiveTriggers.triggerMethod3()");
+
+        logExpected("calling TestRecursiveTriggers.triggerMethod2()");
+        logExpected("triggerMethod2 : triggered");
+        logExpected("triggerMethod1 : triggered with 2");
+        logExpected("inside TestRecursiveTriggers.triggerMethod1(2)");
+        logExpected("inside TestRecursiveTriggers.triggerMethod2()");
+        logExpected("called TestRecursiveTriggers.triggerMethod2()");
+
+        return super.getExpected();
+    }
+}
\ No newline at end of file



More information about the jboss-svn-commits mailing list