[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