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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Aug 3 10:11:47 EDT 2009


Author: adinn
Date: 2009-08-03 10:11:46 -0400 (Mon, 03 Aug 2009)
New Revision: 28752

Added:
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Joiner.java
Modified:
   labs/jbosstm/workspace/adinn/byteman/trunk/docs/ProgrammersGuide.odt
   labs/jbosstm/workspace/adinn/byteman/trunk/docs/ProgrammersGuide.pdf
   labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java
Log:
added Joiner and associated built-ins to allow intoprduction of join dependencies between threads. also updated docs with this and with details of deleteRendezvous fixes BYTEMAN-18 and BYTEMAN-19

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/docs/ProgrammersGuide.odt
===================================================================
(Binary files differ)

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/docs/ProgrammersGuide.pdf
===================================================================
(Binary files differ)

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-08-03 13:44:47 UTC (rev 28751)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/rule/helper/Helper.java	2009-08-03 14:11:46 UTC (rev 28752)
@@ -25,16 +25,11 @@
 
 import org.jboss.byteman.rule.Rule;
 import org.jboss.byteman.rule.exception.ExecuteException;
-import org.jboss.byteman.synchronization.CountDown;
-import org.jboss.byteman.synchronization.Counter;
-import org.jboss.byteman.synchronization.Waiter;
-import org.jboss.byteman.synchronization.Rendezvous;
+import org.jboss.byteman.synchronization.*;
 import org.jboss.byteman.agent.Transformer;
 
 import java.io.*;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.HashSet;
+import java.util.*;
 
 /**
  * This is the default helper class which is used to define builtin operations for rules.
@@ -649,7 +644,102 @@
         return false;
     }
 
+    public boolean createJoin(Object key, int max)
+    {
+        if (max <= 0) {
+            return false;
+        }
 
+        synchronized(joinerMap) {
+            if (joinerMap.get(key) != null) {
+                return false;
+            }
+            joinerMap.put(key, new Joiner(max));
+        }
+
+        return true;
+    }
+
+    public boolean isJoin(Object key, int max)
+    {
+        synchronized(joinerMap) {
+            Joiner joiner = joinerMap.get(key);
+
+            if (joiner == null || joiner.getMax() != max) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean joinEnlist(Object key)
+    {
+        Joiner joiner;
+        synchronized (joinerMap)
+        {
+            joiner = joinerMap.get(key);
+        }
+
+        if (joiner == null) {
+            return false;
+        }
+
+        Thread current = Thread.currentThread();
+
+        switch (joiner.addChild(current)) {
+            case DUPLICATE:
+            case EXCESS:
+            {
+                // failed to add  child
+                return false;
+            }
+            case ADDED:
+            case FILLED:
+            {
+                // added child but parent was not waiting so leave joiner in the map for parent to find
+                return true;
+            }
+            case DONE:
+            default:
+            {
+                // added child and parent was waiting so remove joiner from map now
+                synchronized (joinerMap) {
+                    joinerMap.remove(joiner);
+                }
+                return true;
+            }
+        }
+    }
+
+    public boolean joinWait(Object key, int count)
+    {
+        Joiner joiner;
+        synchronized (joinerMap)
+        {
+            joiner = joinerMap.get(key);
+        }
+
+        if (joiner == null || joiner.getMax() != count) {
+            return false;
+        }
+
+        Thread current = Thread.currentThread();
+
+        if (joiner.joinChildren(current)) {
+            // successfully joined all child threads so remove joiner form map
+            synchronized (joinerMap) {
+                joinerMap.remove(joiner);
+            }
+            return true;
+        } else {
+            // hmm, another thread must have done the join so leave it do the remove
+            return true;
+        }
+    }
+
+    private static HashMap<Object, Joiner> joinerMap = new HashMap<Object, Joiner>();
+
     // counter support
     /**
      * create a counter identified by the given object with count 0 as its initial count

Added: labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Joiner.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Joiner.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/src/org/jboss/byteman/synchronization/Joiner.java	2009-08-03 14:11:46 UTC (rev 28752)
@@ -0,0 +1,113 @@
+package org.jboss.byteman.synchronization;
+
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * class used by default helper to implement join dependencies between threads
+ */
+public class Joiner
+{
+
+    /**
+     * status values returned from child add method
+     */
+    public enum Status {
+        /**
+         * a DUPLICATE status is returned when a child fails to add itself to the join list because it is already present
+         */
+        DUPLICATE,
+        /**
+         * an EXCESS status is returned when a child fails to add itself to a join list because it already contains the
+         * expected number of children
+         */
+        EXCESS,
+        /**
+         * an ADDED status is returned when a child successfully adds itself to the join list but without reaching
+         * the expected number of children
+         */
+        ADDED,
+        /**
+         * a FILLED status is returned when a child successfully adds itself to the join list reaching the expected
+         * number of children but there is no parent thread waiting for the children
+         */
+        FILLED,
+        /**
+         * a DONE  status is returned when a child successfully adds itself to the join list reaching the expected
+         * number of children and there is a parent thread waiting for the children
+         */
+        DONE
+    }
+
+    private List<Thread> children;
+    private int max;
+    private Thread parent;
+
+    public Joiner(int max)
+    {
+        this.max = max;
+        this.children = new LinkedList<Thread>();
+        this.parent =  null;
+    }
+
+    public int getMax()
+    {
+        return max;
+    }
+
+    public synchronized Status addChild(Thread thread)
+    {
+        if (children.contains(thread)) {
+            return Status.DUPLICATE;
+        }
+
+        int size = children.size();
+
+        if (size == max) {
+            return Status.EXCESS;
+        }
+
+        children.add(thread);
+        size++;
+
+        if (size == max) {
+            if (parent ==  null) {
+                return Status.FILLED;
+            } else {
+                notifyAll();
+                return Status.DONE;
+            }
+        }
+        return Status.ADDED;
+    }
+
+    public boolean joinChildren(Thread thread)
+    {
+        synchronized (this) {
+            if (parent != null) {
+                return false;
+            }
+            parent = thread;
+            while (children.size() < max) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    // do nothing
+                }
+            }
+        }
+        // since we are the parent and the waiting is over we don't need to stay synchronized
+        for (int i = 0; i < max;) {
+            Thread child = children.get(i);
+            try {
+                child.join();
+            } catch (InterruptedException e) {
+                // try again
+                break;
+            }
+            i++;
+        }
+        return true;
+    }
+}
+



More information about the jboss-svn-commits mailing list