Author: mszefler
Date: Wed Jun 20 10:41:25 2007
New Revision: 549168

URL: http://svn.apache.org/viewvc?view=rev&rev=549168
Log:
Added NStateLatch for hydrationlatch.

Added:
    
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/NStateLatch.java
   (with props)

Added: 
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/NStateLatch.java
URL: 
http://svn.apache.org/viewvc/incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/NStateLatch.java?view=auto&rev=549168
==============================================================================
--- 
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/NStateLatch.java
 (added)
+++ 
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/NStateLatch.java
 Wed Jun 20 10:41:25 2007
@@ -0,0 +1,110 @@
+package org.apache.ode.bpel.engine;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * An N state synchronization latch useful for implementing 
hydration/dehydration. The
+ * latch functions as follows. At any time, the latch is in one of N states 
and has a
+ * count. Clients can "latch" and "release" the latch, which 
increments/decrements the 
+ * count; however, when latching, a state must be specified. If the state does 
not match
+ * the current state, the latch blocks until the count is zero. Essentially, 
the latch
+ * can change state only when the count is zero. Every time the latch changes 
state an 
+ * optional [EMAIL PROTECTED] Runnable} corresponding to the new state is 
executed. 
+ * 
+ * 
+ * @author Maciej Szefler ( m s z e f l e r @ g m a i l . c o m )
+ *
+ */
+public class NStateLatch {
+    
+    /** Current state. */
+    private int _state = -1;
+
+    /** Current depth (i.e. number of enter() calls) */
+    private int _depth = 0;
+
+    /** Action for state transition ?-->i */
+    protected Runnable _transitions[];
+    
+    /** Synchronization lock .*/
+    private Lock _lock; 
+    
+    /** _depth == 0 condition. */
+    private Condition _depth0;
+    
+    private boolean _transitioning = false;
+
+    /**
+     * Constructor, the array of [EMAIL PROTECTED] Runnable}s defines the 
number of states and the transition 
+     * actions.  
+     * @param transitions action to perform when entering state x. 
+     */
+    public NStateLatch(Runnable [] transitions) {
+        _transitions = transitions;
+        _lock = new ReentrantLock();
+        _depth0 = _lock.newCondition();
+    }
+    
+    public void latch(int state) {
+        if (state >= _transitions.length || state < 0)
+            throw new IllegalArgumentException("Invalid state.");
+        
+        _lock.lock();
+        try {
+
+            if (_transitioning )
+                throw new IllegalStateException("Manipulating latch from 
transition. ");
+            
+            if (_state != state) {
+                // wait for the depth to become 0
+                while (_depth != 0) 
+                    _depth0.awaitUninterruptibly();
+              
+                if (_state != state) {
+                    if (_transitions[state] != null) 
+                        try {
+                            _transitioning = true;
+                            _transitions[state].run();
+                        } catch (Throwable t) {
+                            t.printStackTrace();
+                        } finally {
+                            _transitioning = false;
+                        }
+
+                        
+                    _state = state;
+                    
+                }
+            }
+
+            _depth ++;
+            
+            
+        } finally {
+            _lock.unlock();
+        }
+    }
+    
+    public void release(int state) {
+        _lock.lock();
+        try {
+            
+            if (_transitioning )
+                throw new IllegalStateException("Manipulating latch from 
transition. ");
+
+            if (_state != state)
+                throw new IllegalStateException("Wrong state.");
+            if (_depth <= 0)
+                throw new IllegalStateException("Too many release() calls.");
+            
+            _depth --;
+            
+            if (_depth == 0)
+                _depth0.signal();
+        } finally {
+            _lock.unlock();
+        }
+    }
+}

Propchange: 
incubator/ode/trunk/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/NStateLatch.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to