You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2011/02/03 23:21:11 UTC

svn commit: r1067008 - in /felix/trunk/coordinator/src: main/java/org/apache/felix/coordination/impl/ main/java/org/apache/felix/jmx/service/coordination/ main/java/org/apache/felix/jmx/service/coordinator/ main/java/org/apache/felix/service/coordinati...

Author: fmeschbe
Date: Thu Feb  3 22:21:10 2011
New Revision: 1067008

URL: http://svn.apache.org/viewvc?rev=1067008&view=rev
Log:
FELIX-2642 Adapt to implementation to R4.3 draft3 specification

Added:
    felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/
    felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java   (contents, props changed)
      - copied, changed from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java   (contents, props changed)
      - copied, changed from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java   (with props)
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java   (with props)
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java   (contents, props changed)
      - copied, changed from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java   (with props)
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java   (contents, props changed)
      - copied, changed from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java   (contents, props changed)
      - copied, changed from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java
Removed:
    felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Coordination.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationException.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Coordinator.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java
Modified:
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CrdCommand.java
    felix/trunk/coordinator/src/test/java/org/apache/felix/coordination/impl/CoordinatorImplTest.java

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java?rev=1067008&r1=1067007&r2=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java Thu Feb  3 22:21:10 2011
@@ -24,8 +24,8 @@ import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
-import org.apache.felix.jmx.service.coordination.CoordinatorMBean;
-import org.apache.felix.service.coordination.Coordinator;
+import org.apache.felix.jmx.service.coordinator.CoordinatorMBean;
+import org.apache.felix.service.coordinator.Coordinator;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java?rev=1067008&r1=1067007&r2=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java Thu Feb  3 22:21:10 2011
@@ -25,8 +25,9 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.TimerTask;
 
-import org.apache.felix.service.coordination.Coordination;
-import org.apache.felix.service.coordination.Participant;
+import org.apache.felix.service.coordinator.Coordination;
+import org.apache.felix.service.coordinator.CoordinationException;
+import org.apache.felix.service.coordinator.Participant;
 
 @SuppressWarnings("deprecation")
 public class CoordinationImpl implements Coordination
@@ -41,9 +42,6 @@ public class CoordinationImpl implements
     /** Coordination completed */
     private static final int TERMINATED = 3;
 
-    /** Coordination failed */
-    private static final int FAILED = 4;
-
     private final CoordinatorImpl owner;
 
     private final long id;
@@ -51,7 +49,7 @@ public class CoordinationImpl implements
     private final String name;
 
     // TODO: timeout must be enforced
-    private long timeOutInMs;
+    private long deadLine;
 
     /**
      * Access to this field must be synchronized as long as the expected state
@@ -61,8 +59,6 @@ public class CoordinationImpl implements
      */
     private volatile int state;
 
-    private int mustFail;
-
     private Throwable failReason;
 
     private ArrayList<Participant> participants;
@@ -73,137 +69,130 @@ public class CoordinationImpl implements
 
     private Thread initiatorThread;
 
-    public CoordinationImpl(final CoordinatorImpl owner, final long id, final String name, final long defaultTimeOutInMs)
+    public CoordinationImpl(final CoordinatorImpl owner, final long id, final String name, final int timeOutInMs)
     {
+        // TODO: validate name against Bundle Symbolic Name pattern
+
         this.owner = owner;
         this.id = id;
         this.name = name;
-        this.mustFail = 0;
         this.state = ACTIVE;
         this.participants = new ArrayList<Participant>();
         this.variables = new HashMap<Class<?>, Object>();
-        this.timeOutInMs = -defaultTimeOutInMs;
+        this.deadLine = (timeOutInMs > 0) ? System.currentTimeMillis() + timeOutInMs : 0;
         this.initiatorThread = Thread.currentThread();
 
-        scheduleTimeout(defaultTimeOutInMs);
+        scheduleTimeout(deadLine);
     }
 
-    public String getName()
-    {
-        return name;
-    }
-
-    long getId()
+    public long getId()
     {
         return this.id;
     }
 
-    void mustFail(final Throwable reason)
-    {
-        this.mustFail = FAILED;
-        this.failReason = reason;
-    }
-
-    /**
-     * Initiates a coordination timeout. Called from the timer task scheduled by
-     * the {@link #scheduleTimeout(long)} method.
-     * <p>
-     * This method is inteded to only be called from the scheduled timer task.
-     */
-    void timeout()
-    {
-        // If a timeout happens, the coordination thread is set to always fail
-        this.mustFail = TIMEOUT;
-
-        // Fail the Coordination upon timeout
-        fail(null);
-    }
-
-    long getTimeOut()
+    public String getName()
     {
-        return this.timeOutInMs;
+        return name;
     }
 
-    public int end() throws IllegalStateException
+    public boolean fail(Throwable reason)
     {
         if (startTermination())
         {
-            if (mustFail != 0)
+            this.failReason = reason;
+
+            // consider failure reason (if not null)
+            for (Participant part : participants)
             {
-                failInternal();
-                return mustFail;
+                try
+                {
+                    part.failed(this);
+                }
+                catch (Exception e)
+                {
+                    // TODO: log
+                }
+
+                // release the participant for other coordinations
+                owner.releaseParticipant(part);
             }
-            return endInternal();
-        }
 
-        // already terminated
-        throw new IllegalStateException();
-    }
+            state = TERMINATED;
+
+            synchronized (this)
+            {
+                this.notifyAll();
+            }
 
-    public boolean fail(Throwable reason)
-    {
-        if (startTermination())
-        {
-            this.failReason = reason;
-            failInternal();
             return true;
         }
         return false;
     }
 
-    public boolean terminate()
+    public void end()
     {
-        if (state == ACTIVE)
+        if (startTermination())
         {
-            try
+            boolean partialFailure = false;
+            for (Participant part : participants)
             {
-                end();
-                return true;
+                try
+                {
+                    part.ended(this);
+                }
+                catch (Exception e)
+                {
+                    // TODO: log
+                    partialFailure = true;
+                }
+
+                // release the participant for other coordinations
+                owner.releaseParticipant(part);
             }
-            catch (IllegalStateException ise)
+
+            state = TERMINATED;
+
+            synchronized (this)
+            {
+                this.notifyAll();
+            }
+
+            if (partialFailure)
             {
-                // another thread might have started the termination just
-                // after the current thread checked the state but before the
-                // end() method called on this thread was able to change the
-                // state. Just ignore this exception and continue.
+                throw new CoordinationException("One or more participants threw while ending the coordination", this,
+                    CoordinationException.PARTIALLY_ENDED);
             }
         }
-        return false;
+        else
+        {
+            // already terminated
+            throw new CoordinationException("Coordination " + id + "/" + name + " has already terminated", this,
+                CoordinationException.ALREADY_ENDED);
+        }
     }
 
-    /**
-     * Returns whether the coordination has ended in failure.
-     * <p>
-     * The return value of <code>false</code> may be a transient situation if
-     * the coordination is in the process of terminating due to a failure.
-     */
-    public boolean isFailed()
-    {
-        return state == FAILED;
-    }
 
-    /**
-     * Returns whether the coordination has ended.
-     * <p>
-     * The return value of <code>false</code> may be a transient situation if
-     * the coordination is in the process of terminating.
-     */
-    public boolean isTerminated()
-    {
-        return state == TERMINATED || state == FAILED;
-    }
-
-    public void addTimeout(long timeOutInMs)
+    public Collection<Participant> getParticipants()
     {
-        if (this.timeOutInMs > 0)
+        // synchronize access to the state to prevent it from being changed
+        // while we create a copy of the participant list
+        synchronized (this)
         {
-            // already set, ignore
+            if (state == ACTIVE)
+            {
+                return new ArrayList<Participant>(participants);
+            }
         }
 
-        this.timeOutInMs = timeOutInMs;
-        scheduleTimeout(timeOutInMs);
+        return Collections.<Participant> emptyList();
     }
 
+    public Throwable getFailure()
+    {
+        return failReason;
+    }
+
+
     /**
      * Adds the participant to the end of the list of participants of this
      * coordination.
@@ -217,7 +206,7 @@ public class CoordinationImpl implements
      *             the participant cannot currently participate in this
      *             coordination
      */
-    public boolean participate(Participant p)
+    public void addParticipant(Participant p)
     {
 
         // ensure participant only pariticipates on a single coordination
@@ -229,36 +218,98 @@ public class CoordinationImpl implements
         // while adding the participant
         synchronized (this)
         {
-            if (state == ACTIVE)
+            if (isTerminated())
             {
-                if (!participants.contains(p))
-                {
-                    participants.add(p);
-                }
-                return true;
+                owner.releaseParticipant(p);
+
+                throw new CoordinationException("Cannot add Participant " + p + " to terminated Coordination", this,
+                    (getFailure() != null) ? CoordinationException.FAILED : CoordinationException.ALREADY_ENDED);
+            }
+
+            if (!participants.contains(p))
+            {
+                participants.add(p);
             }
-            return false;
         }
     }
 
-    public Collection<Participant> getParticipants()
+    public Map<Class<?>, ?> getVariables()
+    {
+        return variables;
+    }
+
+    public long extendTimeout(long timeOutInMs)
     {
-        // synchronize access to the state to prevent it from being changed
-        // while we create a copy of the participant list
         synchronized (this)
         {
-            if (state == ACTIVE)
+            if (isTerminated())
             {
-                return new ArrayList<Participant>(participants);
+                throw new CoordinationException("Cannot extend timeout on terminated Coordination", this,
+                    (getFailure() != null) ? CoordinationException.FAILED : CoordinationException.ALREADY_ENDED);
             }
+
+            if (timeOutInMs > 0)
+            {
+                this.deadLine += timeOutInMs;
+                scheduleTimeout(this.deadLine);
+            }
+
+            return this.deadLine;
         }
+    }
 
-        return Collections.<Participant> emptyList();
+    /**
+     * Returns whether the coordination has ended.
+     * <p>
+     * The return value of <code>false</code> may be a transient situation if
+     * the coordination is in the process of terminating.
+     */
+    public boolean isTerminated()
+    {
+        return state != ACTIVE;
     }
 
-    public Map<Class<?>, ?> getVariables()
+    public Thread getThread()
     {
-        return variables;
+        return initiatorThread;
+    }
+
+    public void join(long timeoutInMillis) throws InterruptedException
+    {
+        synchronized (this)
+        {
+            if (!isTerminated())
+            {
+                this.wait(timeoutInMillis);
+            }
+        }
+    }
+
+    public Coordination push()
+    {
+        // TODO: Check whether this has already been pushed !
+        // throw new CoordinationException("Coordination already pushed", this, CoordinationException.ALREADY_PUSHED);
+
+        return owner.push(this);
+    }
+
+    //-------
+
+    /**
+     * Initiates a coordination timeout. Called from the timer task scheduled by
+     * the {@link #scheduleTimeout(long)} method.
+     * <p>
+     * This method is inteded to only be called from the scheduled timer task.
+     */
+    void timeout()
+    {
+        // Fail the Coordination upon timeout
+        fail(TIMEOUT);
+    }
+
+    long getDeadLine()
+    {
+        return this.deadLine;
     }
 
     /**
@@ -288,72 +339,13 @@ public class CoordinationImpl implements
     }
 
     /**
-     * Internal implemenation of successful termination of the coordination.
-     * <p>
-     * This method must only be called after the {@link #state} field has been
-     * set to {@link State#TERMINATING} and only be the method successfully
-     * setting this state.
-     *
-     * @return OK or PARTIALLY_ENDED depending on whether all participants
-     *         succeeded or some of them failed ending the coordination.
-     */
-    private int endInternal()
-    {
-        int reason = OK;
-        for (Participant part : participants)
-        {
-            try
-            {
-                part.ended(this);
-            }
-            catch (Exception e)
-            {
-                // TODO: log
-                reason = PARTIALLY_ENDED;
-            }
-
-            // release the participant for other coordinations
-            owner.releaseParticipant(part);
-        }
-        state = TERMINATED;
-        return reason;
-    }
-
-    /**
-     * Internal implemenation of coordination failure.
-     * <p>
-     * This method must only be called after the {@link #state} field has been
-     * set to {@link State#TERMINATING} and only be the method successfully
-     * setting this state.
-     */
-    private void failInternal()
-    {
-        // consider failure reason (if not null)
-        for (Participant part : participants)
-        {
-            try
-            {
-                part.failed(this);
-            }
-            catch (Exception e)
-            {
-                // TODO: log
-            }
-
-            // release the participant for other coordinations
-            owner.releaseParticipant(part);
-        }
-        state = FAILED;
-    }
-
-    /**
      * Helper method for timeout scheduling. If a timer is currently scheduled
      * it is canceled. If the new timeout value is a positive value a new timer
-     * is scheduled to fire of so many milliseconds from now.
+     * is scheduled to fire at the desired time (in the future)
      *
-     * @param timeout The new timeout value
+     * @param deadline The at which to schedule the timer
      */
-    private void scheduleTimeout(final long timeout)
+    private void scheduleTimeout(final long deadLine)
     {
         if (timeoutTask != null)
         {
@@ -361,7 +353,7 @@ public class CoordinationImpl implements
             timeoutTask = null;
         }
 
-        if (timeout > 0)
+        if (deadLine > System.currentTimeMillis())
         {
             timeoutTask = new TimerTask()
             {
@@ -372,7 +364,7 @@ public class CoordinationImpl implements
                 }
             };
 
-            owner.schedule(timeoutTask, timeout);
+            owner.schedule(timeoutTask, deadLine);
         }
     }
 }

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java?rev=1067008&r1=1067007&r2=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java Thu Feb  3 22:21:10 2011
@@ -21,6 +21,7 @@ package org.apache.felix.coordination.im
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Stack;
@@ -35,10 +36,10 @@ import javax.management.openmbean.OpenDa
 import javax.management.openmbean.TabularData;
 import javax.management.openmbean.TabularDataSupport;
 
-import org.apache.felix.jmx.service.coordination.CoordinatorMBean;
-import org.apache.felix.service.coordination.Coordination;
-import org.apache.felix.service.coordination.CoordinationException;
-import org.apache.felix.service.coordination.Participant;
+import org.apache.felix.jmx.service.coordinator.CoordinatorMBean;
+import org.apache.felix.service.coordinator.Coordination;
+import org.apache.felix.service.coordinator.CoordinationException;
+import org.apache.felix.service.coordinator.Participant;
 
 /**
  * The <code>CoordinationMgr</code> is the actual backend manager of all
@@ -117,15 +118,15 @@ public class CoordinationMgr implements 
         this.participationTimeOut = participationTimeout;
     }
 
-    void schedule(final TimerTask task, final long delay)
+    void schedule(final TimerTask task, final long deadLine)
     {
-        if (delay < 0)
+        if (deadLine < 0)
         {
             task.cancel();
         }
         else
         {
-            coordinationTimer.schedule(task, delay);
+            coordinationTimer.schedule(task, new Date(deadLine));
         }
     }
 
@@ -139,20 +140,29 @@ public class CoordinationMgr implements 
             CoordinationImpl current = participants.get(p);
             while (current != null && current != c)
             {
+                if (current.getThread() == c.getThread())
+                {
+                    throw new CoordinationException("Participant " + p + " already participating in Coordination "
+                        + current.getId() + "/" + current.getName() + " in this thread", c,
+                        CoordinationException.DEADLOCK_DETECTED);
+                }
+
                 try
                 {
                     participants.wait(waitTime);
                 }
                 catch (InterruptedException ie)
                 {
-                    // don't worry, just keep on waiting
+                    throw new CoordinationException("Interrupted waiting to add Participant " + p
+                        + " currently participating in Coordination " + current.getId() + "/" + current.getName()
+                        + " in this thread", c, CoordinationException.LOCK_INTERRUPTED);
                 }
 
                 // timeout waiting for participation
                 if (System.currentTimeMillis() > cutOff)
                 {
-                    throw new CoordinationException("Timed out waiting to join coordinaton", c.getName(),
-                        CoordinationException.TIMEOUT);
+                    throw new CoordinationException("Timed out waiting to join coordinaton", c,
+                        CoordinationException.UNKNOWN);
                 }
 
                 // check again
@@ -175,10 +185,10 @@ public class CoordinationMgr implements 
 
     // ---------- Coordinator back end implementation
 
-    Coordination create(final CoordinatorImpl owner, final String name)
+    Coordination create(final CoordinatorImpl owner, final String name, final int timeout)
     {
         long id = ctr.incrementAndGet();
-        CoordinationImpl c = new CoordinationImpl(owner, id, name, defaultTimeOut);
+        CoordinationImpl c = new CoordinationImpl(owner, id, name, timeout);
         coordinations.put(id, c);
         return c;
     }
@@ -214,7 +224,7 @@ public class CoordinationMgr implements 
         return null;
     }
 
-    Coordination getCurrentCoordination()
+    Coordination peek()
     {
         Stack<Coordination> stack = threadStacks.get();
         if (stack != null && !stack.isEmpty())
@@ -235,6 +245,12 @@ public class CoordinationMgr implements 
         return result;
     }
 
+    Coordination getCoordinationById(final long id)
+    {
+        CoordinationImpl c = coordinations.get(id);
+        return (c == null || c.isTerminated()) ? null : c;
+    }
+
     // ---------- CoordinatorMBean interface
 
     public TabularData listCoordinations(String regexFilter)
@@ -260,12 +276,12 @@ public class CoordinationMgr implements 
 
     public CompositeData getCoordination(long id) throws IOException
     {
-        CoordinationImpl c = coordinations.get(id);
+        Coordination c = getCoordinationById(id);
         if (c != null)
         {
             try
             {
-                return fromCoordination(c);
+                return fromCoordination((CoordinationImpl) c);
             }
             catch (OpenDataException e)
             {
@@ -277,7 +293,7 @@ public class CoordinationMgr implements 
 
     public boolean fail(long id, String reason)
     {
-        Coordination c = coordinations.get(id);
+        Coordination c = getCoordinationById(id);
         if (c != null)
         {
             return c.fail(new Exception(reason));
@@ -287,10 +303,10 @@ public class CoordinationMgr implements 
 
     public void addTimeout(long id, long timeout)
     {
-        Coordination c = coordinations.get(id);
+        Coordination c = getCoordinationById(id);
         if (c != null)
         {
-            c.addTimeout(timeout);
+            c.extendTimeout(timeout);
         }
     }
 
@@ -298,6 +314,6 @@ public class CoordinationMgr implements 
     {
         return new CompositeDataSupport(COORDINATION_TYPE, new String[]
             { ID, NAME, TIMEOUT }, new Object[]
-            { c.getId(), c.getName(), c.getTimeOut() });
+            { c.getId(), c.getName(), c.getDeadLine() });
     }
 }

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java?rev=1067008&r1=1067007&r2=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java Thu Feb  3 22:21:10 2011
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License. You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -22,10 +22,10 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.TimerTask;
 
-import org.apache.felix.service.coordination.Coordination;
-import org.apache.felix.service.coordination.CoordinationException;
-import org.apache.felix.service.coordination.Coordinator;
-import org.apache.felix.service.coordination.Participant;
+import org.apache.felix.service.coordinator.Coordination;
+import org.apache.felix.service.coordinator.CoordinationException;
+import org.apache.felix.service.coordinator.Coordinator;
+import org.apache.felix.service.coordinator.Participant;
 import org.osgi.framework.Bundle;
 
 @SuppressWarnings("deprecation")
@@ -51,7 +51,7 @@ public class CoordinatorImpl implements 
      * <p>
      * Called by the Coordinator ServiceFactory when this CoordinatorImpl
      * instance is not used any longer by the owner bundle.
-     * 
+     *
      * @see FELIX-2671/OSGi Bug 104
      */
     void dispose()
@@ -80,10 +80,10 @@ public class CoordinatorImpl implements 
         }
     }
 
-    public Coordination create(String name)
+    public Coordination create(final String name, final int timeout)
     {
         // TODO: check permission
-        Coordination c = mgr.create(this, name);
+        Coordination c = mgr.create(this, name, timeout);
         synchronized (coordinations)
         {
             coordinations.add(c);
@@ -91,58 +91,65 @@ public class CoordinatorImpl implements 
         return c;
     }
 
-    public Coordination begin(String name)
+    public Collection<Coordination> getCoordinations()
     {
         // TODO: check permission
-        return push(create(name));
+        return mgr.getCoordinations();
     }
 
-    public Coordination push(Coordination c)
+    public boolean fail(Throwable reason)
     {
         // TODO: check permission
-        return mgr.push(c);
+        CoordinationImpl current = (CoordinationImpl) peek();
+        if (current != null)
+        {
+            return current.fail(reason);
+        }
+        return false;
     }
 
-    public Coordination pop()
+    public Coordination peek()
     {
         // TODO: check permission
-        return mgr.pop();
+        return mgr.peek();
+    }
+
+    public Coordination begin(final String name, final int timeoutInMillis)
+    {
+        // TODO: check permission
+        return push(create(name, timeoutInMillis));
     }
 
-    public Coordination getCurrentCoordination()
+    public Coordination pop()
     {
         // TODO: check permission
-        return mgr.getCurrentCoordination();
+        return mgr.pop();
     }
 
-    public boolean alwaysFail(Throwable reason)
+    public boolean addParticipant(Participant participant) throws CoordinationException
     {
         // TODO: check permission
-        CoordinationImpl current = (CoordinationImpl) getCurrentCoordination();
+        Coordination current = peek();
         if (current != null)
         {
-            current.mustFail(reason);
+            current.addParticipant(participant);
             return true;
         }
         return false;
     }
 
-    public Collection<Coordination> getCoordinations()
+    public Coordination getCoordination(long id)
     {
         // TODO: check permission
-        return mgr.getCoordinations();
+        return mgr.getCoordinationById(id);
     }
 
-    public boolean participate(Participant participant) throws CoordinationException
+    //----------
+
+    Coordination push(Coordination c)
     {
         // TODO: check permission
-        Coordination current = getCurrentCoordination();
-        if (current != null)
-        {
-            current.participate(participant);
-            return true;
-        }
-        return false;
+        return mgr.push(c);
     }
 
     void unregister(final CoordinationImpl c)
@@ -154,9 +161,9 @@ public class CoordinatorImpl implements 
         }
     }
 
-    void schedule(final TimerTask task, final long delay)
+    void schedule(final TimerTask task, final long deadLine)
     {
-        mgr.schedule(task, delay);
+        mgr.schedule(task, deadLine);
     }
 
     void lockParticipant(final Participant p, final CoordinationImpl c)

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CrdCommand.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CrdCommand.java?rev=1067008&r1=1067007&r2=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CrdCommand.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordination/impl/CrdCommand.java Thu Feb  3 22:21:10 2011
@@ -21,8 +21,8 @@ package org.apache.felix.coordination.im
 import java.util.Collection;
 import java.util.Hashtable;
 
-import org.apache.felix.service.coordination.Coordination;
-import org.apache.felix.service.coordination.Participant;
+import org.apache.felix.service.coordinator.Coordination;
+import org.apache.felix.service.coordinator.Participant;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;

Copied: felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java (from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java)
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java?p2=felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java&p1=felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java&r1=1066995&r2=1067008&rev=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java Thu Feb  3 22:21:10 2011
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.felix.jmx.service.coordination;
+package org.apache.felix.jmx.service.coordinator;
 
 import java.io.IOException;
 

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/CoordinatorMBean.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Copied: felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java (from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java)
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java?p2=felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java&p1=felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java&r1=1066995&r2=1067008&rev=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java Thu Feb  3 22:21:10 2011
@@ -34,5 +34,5 @@
  * @Provisional
  */
 @Deprecated
-package org.apache.felix.jmx.service.coordination;
+package org.apache.felix.jmx.service.coordinator;
 

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/jmx/service/coordinator/package-info.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java?rev=1067008&view=auto
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java (added)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java Thu Feb  3 22:21:10 2011
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.service.coordinator;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A Coordination object is used to coordinate a number of independent
+ * participants. Once a Coordination is created, it can be used to add
+ * Participant objects. When the Coordination is ended, the participants are
+ * called back. A Coordination can also fail for various reasons, in that case
+ * the participants are informed of this failure.
+ *
+ * @ThreadSafe
+ * @Provisional
+ */
+@Deprecated
+public interface Coordination
+{
+
+    /**
+     * The TIMEOUT exception is a singleton exception that will the reason for
+     * the failure when the Coordination times out.
+     */
+    public static final Exception TIMEOUT = new Exception();
+
+    /**
+     * A system assigned ID unique for a specific registered Coordinator. This
+     * id must not be reused as long as the Coordinator is registered and must
+     * be monotonically increasing for each Coordination and always be positive.
+     *
+     * @return an id
+     */
+    long getId();
+
+    /**
+     * Return the name of this Coordination. The name is given in the
+     * {@link Coordinator#begin(String, int)} or
+     * {@link Coordinator#create(String, int)} method. The name should follow
+     * the same naming pattern as a Bundle Symbolc Name.
+     *
+     * @return the name of this Coordination
+     */
+    String getName();
+
+    /**
+     * Fail this Coordination. If this Coordination is not terminated, fail it
+     * and call the {@link Participant#failed(Coordination)} method on all
+     * participant on the current thread. Participants must assume that the
+     * Coordination failed and should discard and cleanup any work that was
+     * processed during this Coordination. The {@link #fail(Throwable)} method
+     * will return <code>true</code> if it caused the termination. A fail method
+     * must return silently when the Coordination has already finished and
+     * return <code>false</code>. The fail method must terminate the current
+     * Coordination before any of the failed methods are called. That is, the
+     * {@link Participant#failed(Coordination)} methods must be running outside
+     * the current coordination, adding participants during this phase will
+     * cause a Configuration Exception to be thrown. If the Coordination is
+     * pushed on the Coordinator stack it is associated with a specific thread.
+     *
+     * @param reason The reason of the failure, must not be <code>null</code>
+     * @return true if the Coordination was active and this coordination was
+     *         terminated due to this call, otherwise false
+     */
+    boolean fail(Throwable reason);
+
+    /**
+     * End the current Coordination.
+     *
+     * <pre>
+     * void foo() throws CoordinationException
+     * {
+     *     Coordination c = coordinator.begin(&quot;work&quot;, 0);
+     *     try
+     *     {
+     *         doWork();
+     *     }
+     *     catch (Exception e)
+     *     {
+     *         c.fail(e);
+     *     }
+     *     finally
+     *     {
+     *         c.end();
+     *     }
+     * }
+     * </pre>
+     *
+     * If the coordination was terminated this method throws a Configuration
+     * Exception. Otherwise, any participants will be called on their
+     * {@link Participant#ended(Coordination)} method. A successful return of
+     * this {@link #end()} method indicates that the Coordination has properly
+     * terminated and any participants have been informed of the positive
+     * outcome. It is possible that one of the participants throws an exception
+     * during the callback. If this happens, the coordination fails partially
+     * and this is reported with an exception. This method must terminate the
+     * current Coordination before any of the
+     * {@link Participant#ended(Coordination)} methods are called. That is, the
+     * {@link Participant#ended(Coordination)} methods must be running outside
+     * the current coordination, no participants can be added during the
+     * termination phase. If the Coordination is on a thread local stack then it
+     * must be removed from this stack during termination.
+     *
+     * @throws CoordinationException when the Coordination has (partially)
+     *             failed or timed out.
+     *             <ol>
+     *             <li>{@link CoordinationException#PARTIALLY_ENDED}</li>
+     *             <li>{@link CoordinationException#ALREADY_ENDED}</li>
+     *             <li>{@link CoordinationException#FAILED}</li>
+     *             <li>{@link CoordinationException#UNKNOWN}</li>
+     *             </ol>
+     */
+    void end() throws CoordinationException;
+
+    /**
+     * Return a mutable snapshot of the participants that joined the
+     * Coordination. Each unique Participant object as defined by its identity
+     * occurs only once in this list.
+     *
+     * @return list of participants.
+     * @throws SecurityException This method requires the
+     *             {@link CoordinationPermission#ADMIN} action for the
+     *             {@link CoordinationPermission}.
+     */
+    Collection<Participant> getParticipants();
+
+    /**
+     * If the coordination has failed because {@link #fail(Throwable)} was
+     * called then this method can provide the Throwable that was given as
+     * argument to the {@link #fail(Throwable)} method. A timeout on this
+     * Coordination will set the failure to a TimeoutException.
+     *
+     * @return a Throwable if this Coordination has failed, otherwise
+     *         <code>null</code> if no failure occurred.
+     */
+    Throwable getFailure();
+
+    /**
+     * Add a Participant to this Coordination. Once a Participant is
+     * participating it is guaranteed to receive a call back on either the
+     * {@link Participant#ended(Coordination)} or
+     * {@link Participant#failed(Coordination)} method when the Coordination is
+     * terminated. A participant can be added to the Coordination multiple times
+     * but it must only be called back once when the Coordination is terminated.
+     * A Participant can only participate at a single Coordination, if it
+     * attempts to block at another Coordination, then it will block until prior
+     * Coordinations are finished. Notice that in edge cases the call back can
+     * happen before this method returns. The ordering of the call-backs must
+     * follow the order of participation. If participant is participating
+     * multiple times the first time it participates defines this order.
+     * *@param participant The participant of the Coordination
+     *
+     * @throws CoordinationException This exception should normally not be
+     *             caught by the caller but allowed to bubble up to the
+     *             initiator of the coordination, it is therefore a
+     *             <code>RuntimeException</code>. It signals that this
+     *             participant could not
+     *             participate the current coordination. This can be cause by
+     *             the following reasons:
+     *             <ol>
+     *             <li>{@link CoordinationException#DEADLOCK_DETECTED}</li>
+     *             <li>{@link CoordinationException#ALREADY_ENDED}</li>
+     *             <li>{@link CoordinationException#LOCK_INTERRUPTED}</li>
+     *             <li>{@link CoordinationException#FAILED}</li>
+     *             <li>{@link CoordinationException#UNKNOWN}</li>
+     *             </ol>
+     * @throws SecurityException This method requires the
+     *             {@link CoordinationPermission#PARTICIPATE} action for the
+     *             current Coordination, if any.
+     */
+    void addParticipant(Participant participant);
+
+    /**
+     * A utility map associated with the current Coordination. Each coordination
+     * carries a map that can be used for communicating between different
+     * participants. To namespace of the map is a class, allowing for private
+     * date to be stored in the map by using implementation classes or shared
+     * data by interfaces. The returned map is does not have to not
+     * synchronized. Users of this map must synchronize on the Map object while
+     * making changes.
+     *
+     * @return The map
+     */
+    Map<Class<?>, ?> getVariables();
+
+    /**
+     * Extend the time out. Allows participants to extend the timeout of the
+     * coordination with at least the given amount. This can be done by
+     * participants when they know a task will take more than normal time. This
+     * method returns the new deadline. Passing 0 will return the existing
+     * deadline.
+     *
+     * @param timeInMillis Add this timeout to the current timeout. If the
+     *            current timeout was set to 0, no extension must take place. A
+     *            zero or negative value must have no effect.
+     * @return the new deadline in the format of
+     *         <code>System.currentTimeMillis()</code> or 0 if no timeout was
+     *         set.
+     * @throws CoordinationException Can throw
+     *             <ol>
+     *             <li>{@link CoordinationException#ALREADY_ENDED}</li>
+     *             <li>{@link CoordinationException#FAILED}</li>
+     *             <li>{@link CoordinationException#UNKNOWN}</li>
+     *             </ol>
+     */
+    long extendTimeout(long timeInMs) throws CoordinationException;
+
+    /**
+     * @return true if this Coordination has terminated otherwise false.
+     */
+    boolean isTerminated();
+
+    /**
+     * Answer the associated thread or null.
+     *
+     * @return Associated thread or null
+     */
+    Thread getThread();
+
+    /**
+     * Wait until the Coordination is terminated and all Participant objects
+     * have been called.
+     *
+     * @param timeoutInMillis Maximum time to wait, 0 is forever
+     * @throws InterruptedException If the wait is interrupted
+     */
+    void join(long timeoutInMillis) throws InterruptedException;
+
+    /**
+     * Associate the given Coordination object with a thread local stack of its
+     * Coordinator. The top of the thread local stack is returned with the
+     * {@link Coordinator#peek()} method. To remove the Coordination from the
+     * top call {@link Coordinator#pop()}.
+     *
+     * @return this (for the builder pattern purpose)
+     * @throws CoordinationException Can throw the
+     *             <ol>
+     *             <li>{@link CoordinationException#ALREADY_PUSHED}</li>
+     *             <li>{@link CoordinationException#UNKNOWN}</li>
+     *             </ol>
+     */
+    Coordination push() throws CoordinationException;
+}

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordination.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java?rev=1067008&view=auto
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java (added)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java Thu Feb  3 22:21:10 2011
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.service.coordinator;
+
+/**
+ * Thrown when an implementation detects a potential deadlock situation that it
+ * cannot solve. The name of the current coordination is given as argument.
+ *
+ * @Provisional
+ */
+@Deprecated
+public class CoordinationException extends RuntimeException
+{
+
+    private static final long serialVersionUID = -4466063711012717361L;
+
+    /**
+     * Unknown reason fot this exception.
+     */
+    public static final int UNKNOWN = 0;
+
+    /**
+     * Adding a participant caused a deadlock.
+     */
+    public static final int DEADLOCK_DETECTED = 1;
+
+    /**
+     * The Coordination was failed with {@link Coordination#fail(Throwable)}.
+     * When this exception type is used, the {@link Coordination#getFailure()}
+     * method must return a non-null value.
+     */
+    public static final int FAILED = 3;
+
+    /**
+     * The Coordination was partially ended.
+     */
+    public static final int PARTIALLY_ENDED = 4;
+
+    /**
+     * The Coordination was already ended.
+     */
+    public static final int ALREADY_ENDED = 5;
+
+    /**
+     * A Coordination was pushed on the stack that was already pushed.
+     */
+    public static final int ALREADY_PUSHED = 6;
+
+    /**
+     * Interrupted while trying to lock the participant.
+     */
+    public static final int LOCK_INTERRUPTED = 7;
+
+    /**
+     * The Coordination timed out.
+     */
+    public static final int TIMEOUT = 9;
+
+    private final Coordination coordination;
+
+    private final int type;
+
+    /**
+     * Create a new Coordination Exception.
+     *
+     * @param message The message
+     * @param coordination The coordination that failed
+     * @param type The reason for the exception
+     * @param exception The exception
+     */
+    public CoordinationException(String message, Coordination coordination, int type, Throwable exception)
+    {
+        super(message, exception);
+        this.coordination = coordination;
+        this.type = type;
+    }
+
+    /**
+     * Create a new Coordination Exception.
+     *
+     * @param message The message
+     * @param coordination The coordination that failed
+     * @param type The reason for the exception
+     */
+    public CoordinationException(String message, Coordination coordination, int type)
+    {
+        super(message);
+        this.coordination = coordination;
+        this.type = type;
+    }
+
+    /**
+     * Answer the name of the Coordination associated with this exception.
+     *
+     * @return the Coordination name
+     */
+    public String getName()
+    {
+        return coordination.getName();
+    }
+
+    /**
+     * Answer the reason.
+     *
+     * @return the reason
+     */
+    public int getType()
+    {
+        return type;
+    }
+
+    /**
+     * Must be set if to the exception type is {@link #FAILED}
+     *
+     * @return If exception is {@link #FAILED} a Throwable
+     */
+    public Throwable getFailure()
+    {
+        return getCause();
+    }
+
+    /**
+     * @return Answer the id
+     */
+    public long getId()
+    {
+        return coordination.getId();
+    }
+}

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Copied: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java (from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java)
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java?p2=felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java&p1=felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java&r1=1066995&r2=1067008&rev=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java Thu Feb  3 22:21:10 2011
@@ -1,19 +1,19 @@
 /*
  * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.felix.service.coordination;
+package org.apache.felix.service.coordinator;
 
 import java.security.BasicPermission;
 
@@ -82,7 +82,7 @@ import java.security.BasicPermission;
  * </table>
  * </li>
  * </ol>
- * 
+ *
  * @Provisional
  */
 @Deprecated
@@ -110,12 +110,12 @@ public class CoordinationPermission exte
     /**
      * The name parameter specifies a filter condition. The filter asserts the
      * bundle that initiated the Coordination. An implicit grant is made for a
-     * bundle's own coordinations. Parameters:
-     * 
+     * bundle's own coordinations.
+     *
      * @param filterExpression A filter expression asserting the bundle
      *            associated with the coordination.
-     * @param actions A comma separated combination of INITIATE, ADMIN,
-     *            PARTICIPATE.
+     * @param actions A comma separated combination of {@link #INITIATE},
+     *            {@link #ADMIN}, {@link #PARTICIPATE}.
      */
     public CoordinationPermission(String filterExpression, String actions)
     {
@@ -124,12 +124,12 @@ public class CoordinationPermission exte
 
     /**
      * The verification permission
-     * 
+     *
      * @param bundle The bundle that will be the target of the filter
      *            expression.
-     * @param coordinationName The name of the coordination or null
+     * @param coordinationName The name of the coordination or <code>null</code>
      * @param actions The set of actions required, which is a combination of
-     *            INITIATE, ADMIN, PARTICIPATE.
+     *            {@link #INITIATE}, {@link #ADMIN}, {@link #PARTICIPATE}.
      */
     public CoordinationPermission(org.osgi.framework.Bundle bundle, String coordinationName, String actions)
     {

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/CoordinationPermission.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java?rev=1067008&view=auto
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java (added)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java Thu Feb  3 22:21:10 2011
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.service.coordinator;
+
+import java.util.Collection;
+
+/**
+A Coordinator service coordinates activities between different parties. The Coordinator can create Coordination
+objects. Once a Coordination object is created, it can be pushed on a thread local stack {@link Coordination#push()} as
+an implicit parameter for calls to other parties, or it can be passed as an argument. The current top of the thread
+local stack can be obtained with #peek(). The addParticipant(Participant) method on this service or the
+Coordination.addParticipant(Participant) method can be used to participate in a Coordination. Participants
+participate only in a single Coordination, if a Participant object is added to a second Coordination the
+Coordination.addParticipant(Participant) method is blocked until the first Coordination is terminated. A
+Coordination ends correctly when the Coordination.end() method is called before termination or when the
+Coordination fails due to a timeout or a failure. If the Coordination ends correctly, all its participants are called on
+the Participant.ended(Coordination) method, in all other cases the Participant.failed(Coordination) is
+called. The typical usage of the Coordinator service is as follows:
+<pre>
+Coordination coordination = coordinator.begin("mycoordination",0);
+try {
+doWork();
+}
+finally {
+coordination.end();
+}
+</pre>
+In the doWork() method, code can be called that requires a callback at the end of the Coordination. The doWork
+method can then add a Participant to the coordination. This code is for a Participant.
+<pre>
+void doWork() {
+if (coordinator.addParticipant(this)) {
+beginWork();
+}
+else {
+beginWork();
+finishWork();
+}
+}
+void ended() {
+finishWork();
+}
+void failed() {
+undoWork();
+}
+</pre>
+Life cycle. All Coordinations that are begun through this service must automatically fail before this service is
+ungotten.
+ *
+ * @ThreadSafe
+ * @Provisional
+ */
+@Deprecated
+public interface Coordinator
+{
+
+    /**
+     * Create a new Coordination that is not associated with the current thread.
+     * Parameters:
+     *
+     * @param name The name of this coordination, a name does not have to be
+     *            unique.
+     * @param timeout Timeout in milliseconds, less or equal than 0 means no
+     *            timeout
+     * @return The new Coordination object, never <code>null</code>
+     * @throws SecurityException This method requires the
+     *             {@link CoordinationPermission#INITIATE} action, no bundle
+     *             check is done.
+     * @throws IllegalArgumentException when the name does not match the Bundle
+     *             Symbolic Name pattern
+     */
+    Coordination create(String name, int timeout);
+
+    /**
+     * Provide a mutable snapshot collection of all Coordination objects
+     * currently not terminated. Coordinations in
+     * this list can have terminated before this list is returned or any time
+     * thereafter. The returned collection must
+     * only contain the Coordinations for which the caller has
+     * {@link CoordinationPermission#ADMIN}, without this
+     * permission an empty list must be returned.
+     *
+     * @return a list of Coordination objects filtered by
+     *         {@link CoordinationPermission#ADMIN}
+     */
+    Collection<Coordination> getCoordinations();
+
+    /**
+     * Always fail the current Coordination, if it exists. If this is no current
+     * Coordination return <code>false</code>. Otherwise return the result of
+     * {@link Coordination#fail(Throwable)}, which is <code>true</code> in the
+     * case this call terminates the Coordination and <code>false</code>
+     * otherwise.
+     *
+     * <pre>
+     * false - No current Coordination
+     * false - Current Coordination was already terminated
+     * true - Current Coordination got terminated due to this call
+     * </pre>
+     *
+     * @param reason The reason for failure, must not be <code>null</code>.
+     * @return <code>true</code> if there was a current Coordination and it was
+     *         terminated, otherwise <code>false</code>.
+     */
+    boolean fail(Throwable reason);
+
+    /**
+     * Return the current Coordination or <code>null</code>. The current
+     * Coordination is the top of the thread local stack of Coordinations. If
+     * the stack is empty, there is no current Coordination.
+     *
+     * @return <code>null</code> when the thread local stack is empty, otherwise
+     *         the top of the thread local stack of
+     *         Coordinations.
+     */
+    Coordination peek();
+
+    /**
+     * Begin a new Coordination and push it on the thread local stack with
+     * {@link Coordination#push()}.
+     *
+     * @param name The name of this coordination, a name does not have to be
+     *            unique.
+     * @param timeoutInMillis Timeout in milliseconds, less or equal than 0
+     *            means no timeout
+     * @return A new Coordination object
+     * @throws SecurityException This method requires the
+     *             {@link CoordinationPermission#INITIATE} action, no bundle
+     *             check is done.
+     * @throws IllegalArgumentException when the name does not match the Bundle
+     *             Symbolic Name pattern
+     */
+    Coordination begin(String name, int timeoutInMillis);
+
+    /**
+     * Pop the top of the thread local stack of Coordinations. If no current
+     * Coordination is present, return <code>null</code>.
+     *
+     * @return The top of the stack or <code>null</code>
+     */
+    Coordination pop();
+
+    /**
+     * Participate in the current Coordination and return <code>true</code> or
+     * return <code>false</code> if there is none. This method calls
+     * {@link #peek()}, if it is <code>null</code>, it will return
+     * <code>false</code>. Otherwise it will call
+     * {@link Coordination#addParticipant(Participant)}.
+     *
+     * @param participant The participant of the Coordination
+     * @return <code>true</code> if there was a current Coordination that could
+     *         be successfully used to participate, otherwise <code>false</code>
+     *         .
+     * @throws CoordinationException This exception should normally not be
+     *             caught by the caller but allowed to bubble up to the
+     *             initiator of the coordination, it is therefore a
+     *             <code>RuntimeException</code>. It signals that this
+     *             participant could not participate the current coordination.
+     *             This can be cause by the following reasons:
+     *             <ol>
+     *             <li>{@link CoordinationException#DEADLOCK_DETECTED}</li>
+     *             <li>{@link CoordinationException#ALREADY_ENDED}</li>
+     *             <li>{@link CoordinationException#TIMEOUT}</li>
+     *             <li>{@link CoordinationException#UNKNOWN}</li>
+     *             </ol>
+     * @throws SecurityException This method requires the
+     *             {@link CoordinationPermission#PARTICIPATE} action for the
+     *             current
+     *             Coordination, if any.
+     */
+    boolean addParticipant(Participant participant) throws CoordinationException;
+
+    /**
+     * Answer the coordination associated with the given id if it exists.
+     *
+     * @param id The id of the requested Coordination
+     * @return a Coordination with the given ID or <code>null</code> when
+     *         Coordination cannot be found because it never existed or had
+     *         terminated before this call.
+     * @throws SecurityException if the caller has no
+     *             {@link CoordinationPermission#ADMIN} for the requested
+     *             Coordination.
+     */
+    Coordination getCoordination(long id);
+}

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Coordinator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Copied: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java (from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java)
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java?p2=felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java&p1=felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java&r1=1066995&r2=1067008&rev=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java Thu Feb  3 22:21:10 2011
@@ -1,34 +1,33 @@
 /*
  * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.felix.service.coordination;
+package org.apache.felix.service.coordinator;
 
 /**
  * A Participant participates in a Coordination. A Participant can participate
- * in a Coordination by calling Coordinator.participate(Participant) or
- * Coordinator.participateOrBegin(Participant). After successfully initiating
- * the participation, the Participant is called back when the Coordination is
- * terminated. If a Coordination ends with the Coordination.end() method, then
- * all the participants are called back on their ended(Coordination) method. If
- * the initiator decides to fail the Coordination (or another party has called
- * Coordinator.alwaysFail(Throwable)) then the failed(Coordination) method is
- * called back. Participants are required to be thread safe for the
- * ended(Coordination) method and the failed(Coordination) method. Both methods
- * can be called on another thread. A Coordinator service must block a
- * Participant when it tries to participate in multiple Coordinations.
- * 
+ * in a Coordination by calling {@link Coordinator#addParticipant(Participant)}.
+ * After successfully initiating the participation, the Participant is called
+ * back when the Coordination is terminated. If a Coordination ends with the
+ * {@link Coordination#end()} method, then all the participants are called back
+ * on their {@link #ended(Coordination)} method. If the Coordination is failed
+ * (someone has called {@link Coordination#fail(Throwable)} then the
+ * {@link #failed(Coordination)} method is called back. Participants are
+ * required to be thread safe for the {@link #ended(Coordination)} method and
+ * the {@link #failed(Coordination)} method. Both methods can be called on
+ * another thread.
+ *
  * @ThreadSafe
  * @Provisional
  */
@@ -40,7 +39,7 @@ public interface Participant
      * The Coordination has failed and the participant is informed. A
      * participant should properly discard any work it has done during the
      * active coordination.
-     * 
+     *
      * @param c The Coordination that does the callback
      * @throws Exception Any exception thrown should be logged but is further
      *             ignored and does not influence the outcome of the
@@ -50,11 +49,11 @@ public interface Participant
 
     /**
      * The Coordination is being ended.
-     * 
+     *
      * @param c The Coordination that does the callback
      * @throws Exception If an exception is thrown it should be logged and the
-     *             return of the Coordination.end() method must be
-     *             Coordination.PARTIALLY_ENDED.
+     *             return of the {@link Coordination#end()} method must throw
+     *             {@link CoordinationException#PARTIALLY_ENDED}.
      */
     void ended(Coordination c) throws Exception;
 }

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/Participant.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Copied: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java (from r1066995, felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java)
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java?p2=felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java&p1=felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java&r1=1066995&r2=1067008&rev=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java Thu Feb  3 22:21:10 2011
@@ -1,12 +1,12 @@
 /*
  * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 /**
- * Coordination Package Version 1.0.
+ * Coordinator Package Version 1.0.
  * <p>
  * Bundles wishing to use this package must list the package in the
  * Import-Package header of the bundle's manifest.
@@ -23,15 +23,15 @@
  * package and the providers that implement the API in this package.
  * <p>
  * Example import for consumers using the API in this package: <blockquote>
- * <code>Import-Package: org.apache.felix.service.coordination; version="[1.0,2.0)"; status="provisional"</code>
+ * <code>Import-Package: org.apache.felix.service.coordinator; version="[1.0,2.0)"; status="provisional"</code>
  * </blockquote>
  * <p>
  * Example import for providers implementing the API in this package:
  * <blockquote>
- * <code>Import-Package: org.apache.felix.service.coordination; version="[1.0,1.1)"; status="provisional"</code>
+ * <code>Import-Package: org.apache.felix.service.coordinator; version="[1.0,1.1)"; status="provisional"</code>
  * </blockquote>
- * 
+ *
  * @Provisional
  */
 @Deprecated
-package org.apache.felix.service.coordination;
\ No newline at end of file
+package org.apache.felix.service.coordinator;
\ No newline at end of file

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/service/coordinator/package-info.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: felix/trunk/coordinator/src/test/java/org/apache/felix/coordination/impl/CoordinatorImplTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/test/java/org/apache/felix/coordination/impl/CoordinatorImplTest.java?rev=1067008&r1=1067007&r2=1067008&view=diff
==============================================================================
--- felix/trunk/coordinator/src/test/java/org/apache/felix/coordination/impl/CoordinatorImplTest.java (original)
+++ felix/trunk/coordinator/src/test/java/org/apache/felix/coordination/impl/CoordinatorImplTest.java Thu Feb  3 22:21:10 2011
@@ -18,9 +18,9 @@
  */
 package org.apache.felix.coordination.impl;
 
-import org.apache.felix.service.coordination.Coordination;
-import org.apache.felix.service.coordination.CoordinationException;
-import org.apache.felix.service.coordination.Participant;
+import org.apache.felix.service.coordinator.Coordination;
+import org.apache.felix.service.coordinator.CoordinationException;
+import org.apache.felix.service.coordinator.Participant;
 
 import junit.framework.TestCase;
 
@@ -43,129 +43,132 @@ public class CoordinatorImplTest extends
     public void test_createCoordination()
     {
         final String name = "test";
-        final Coordination c1 = coordinator.create(name);
+        final Coordination c1 = coordinator.create(name, 0);
         assertNotNull(c1);
         assertEquals(name, c1.getName());
-        assertNull(coordinator.getCurrentCoordination());
-        assertFalse(c1.isFailed());
+        assertNull(coordinator.peek());
+        assertNull(c1.getFailure());
         assertFalse(c1.isTerminated());
         assertTrue(c1.getParticipants().isEmpty());
 
-        assertTrue(c1.fail(new Exception()));
-        assertTrue(c1.isFailed());
+        Exception cause = new Exception();
+        assertTrue(c1.fail(cause));
+        assertSame(cause, c1.getFailure());
         assertTrue(c1.isTerminated());
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
 
         assertFalse(c1.fail(new Exception()));
         try
         {
             c1.end();
-            fail("Expected IllegalStateException on end() after fail()");
+            fail("Expected CoordinationException.ALREADY_ENDED on end() after fail()");
         }
-        catch (IllegalStateException ise)
+        catch (CoordinationException ce)
         {
-            // expected
+            // expected already terminated
+            assertEquals(CoordinationException.ALREADY_ENDED, ce.getType());
         }
 
-        final Coordination c2 = coordinator.create(name);
+        final Coordination c2 = coordinator.create(name, 0);
         assertNotNull(c2);
         assertEquals(name, c2.getName());
-        assertNull(coordinator.getCurrentCoordination());
-        assertFalse(c2.isFailed());
+        assertNull(coordinator.peek());
+        assertNull(c2.getFailure());
         assertFalse(c2.isTerminated());
         assertTrue(c2.getParticipants().isEmpty());
 
-        assertEquals(Coordination.OK, c2.end());
-        assertFalse(c2.isFailed());
+        c2.end();
+        assertNull(c2.getFailure());
         assertTrue(c2.isTerminated());
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
 
         assertFalse(c2.fail(new Exception()));
         try
         {
             c2.end();
-            fail("Expected IllegalStateException on second end()");
+            fail("Expected CoordinationException.ALREADY_ENDED on second end()");
         }
-        catch (IllegalStateException ise)
+        catch (CoordinationException ce)
         {
-            // expected
+            // expected already terminated
+            assertEquals(CoordinationException.ALREADY_ENDED, ce.getType());
         }
     }
 
     public void test_beginCoordination()
     {
         final String name = "test";
-        final Coordination c1 = coordinator.begin(name);
+        final Coordination c1 = coordinator.begin(name, 0);
         assertNotNull(c1);
         assertEquals(name, c1.getName());
 
-        assertEquals(c1, coordinator.getCurrentCoordination());
+        assertEquals(c1, coordinator.peek());
         assertEquals(c1, coordinator.pop());
 
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
         coordinator.push(c1);
-        assertEquals(c1, coordinator.getCurrentCoordination());
+        assertEquals(c1, coordinator.peek());
 
         c1.end();
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
 
-        final Coordination c2 = coordinator.begin(name);
+        final Coordination c2 = coordinator.begin(name, 0);
         assertNotNull(c2);
         assertEquals(name, c2.getName());
-        assertEquals(c2, coordinator.getCurrentCoordination());
+        assertEquals(c2, coordinator.peek());
         c2.fail(null);
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
     }
 
     public void test_beginCoordination_stack()
     {
         final String name = "test";
 
-        final Coordination c1 = coordinator.begin(name);
+        final Coordination c1 = coordinator.begin(name, 0);
         assertNotNull(c1);
         assertEquals(name, c1.getName());
-        assertEquals(c1, coordinator.getCurrentCoordination());
+        assertEquals(c1, coordinator.peek());
 
-        final Coordination c2 = coordinator.begin(name);
+        final Coordination c2 = coordinator.begin(name, 0);
         assertNotNull(c2);
         assertEquals(name, c2.getName());
-        assertEquals(c2, coordinator.getCurrentCoordination());
+        assertEquals(c2, coordinator.peek());
 
         c2.end();
-        assertEquals(c1, coordinator.getCurrentCoordination());
+        assertEquals(c1, coordinator.peek());
 
         c1.end();
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
     }
 
     public void test_beginCoordination_stack2()
     {
         final String name = "test";
 
-        final Coordination c1 = coordinator.begin(name);
+        final Coordination c1 = coordinator.begin(name, 0);
         assertNotNull(c1);
         assertEquals(name, c1.getName());
-        assertEquals(c1, coordinator.getCurrentCoordination());
+        assertEquals(c1, coordinator.peek());
 
-        final Coordination c2 = coordinator.begin(name);
+        final Coordination c2 = coordinator.begin(name, 0);
         assertNotNull(c2);
         assertEquals(name, c2.getName());
-        assertEquals(c2, coordinator.getCurrentCoordination());
+        assertEquals(c2, coordinator.peek());
 
         c1.end();
-        assertEquals(c2, coordinator.getCurrentCoordination());
+        assertEquals(c2, coordinator.peek());
 
         c2.end();
-        assertNull(coordinator.getCurrentCoordination());
+        assertNull(coordinator.peek());
     }
 
-    public void test_participate_with_ended()
+    public void test_addParticipant_with_ended()
     {
         final String name = "test";
-        final Coordination c1 = coordinator.create(name);
+        final Coordination c1 = coordinator.create(name, 0);
 
         final MockParticipant p1 = new MockParticipant();
-        c1.participate(p1);
+        c1.addParticipant(p1);
         assertTrue(c1.getParticipants().contains(p1));
         assertEquals(1, c1.getParticipants().size());
 
@@ -175,11 +178,11 @@ public class CoordinatorImplTest extends
         assertEquals(c1, p1.c);
 
         // assert order of call
-        final Coordination c2 = coordinator.create(name);
+        final Coordination c2 = coordinator.create(name, 0);
         final MockParticipant p21 = new MockParticipant();
         final MockParticipant p22 = new MockParticipant();
-        c2.participate(p21);
-        c2.participate(p22);
+        c2.addParticipant(p21);
+        c2.addParticipant(p22);
         assertTrue(c2.getParticipants().contains(p21));
         assertTrue(c2.getParticipants().contains(p22));
         assertEquals(2, c2.getParticipants().size());
@@ -192,12 +195,12 @@ public class CoordinatorImplTest extends
         assertTrue("p21 must be called before p22", p21.time < p22.time);
 
         // assert order of call with two registrations
-        final Coordination c3 = coordinator.create(name);
+        final Coordination c3 = coordinator.create(name, 0);
         final MockParticipant p31 = new MockParticipant();
         final MockParticipant p32 = new MockParticipant();
-        c3.participate(p31);
-        c3.participate(p32);
-        c3.participate(p31); // should be "ignored"
+        c3.addParticipant(p31);
+        c3.addParticipant(p32);
+        c3.addParticipant(p31); // should be "ignored"
         assertTrue(c3.getParticipants().contains(p31));
         assertTrue(c3.getParticipants().contains(p32));
         assertEquals(2, c3.getParticipants().size());
@@ -210,13 +213,13 @@ public class CoordinatorImplTest extends
         assertTrue("p21 must be called before p22", p31.time < p32.time);
     }
 
-    public void test_participate_with_failed()
+    public void test_addParticipant_with_failed()
     {
         final String name = "test";
-        final Coordination c1 = coordinator.create(name);
+        final Coordination c1 = coordinator.create(name, 0);
 
         final MockParticipant p1 = new MockParticipant();
-        c1.participate(p1);
+        c1.addParticipant(p1);
         assertTrue(c1.getParticipants().contains(p1));
         assertEquals(1, c1.getParticipants().size());
 
@@ -226,11 +229,11 @@ public class CoordinatorImplTest extends
         assertEquals(c1, p1.c);
 
         // assert order of call
-        final Coordination c2 = coordinator.create(name);
+        final Coordination c2 = coordinator.create(name, 0);
         final MockParticipant p21 = new MockParticipant();
         final MockParticipant p22 = new MockParticipant();
-        c2.participate(p21);
-        c2.participate(p22);
+        c2.addParticipant(p21);
+        c2.addParticipant(p22);
         assertTrue(c2.getParticipants().contains(p21));
         assertTrue(c2.getParticipants().contains(p22));
         assertEquals(2, c2.getParticipants().size());
@@ -243,12 +246,12 @@ public class CoordinatorImplTest extends
         assertTrue("p21 must be called before p22", p21.time < p22.time);
 
         // assert order of call with two registrations
-        final Coordination c3 = coordinator.create(name);
+        final Coordination c3 = coordinator.create(name, 0);
         final MockParticipant p31 = new MockParticipant();
         final MockParticipant p32 = new MockParticipant();
-        c3.participate(p31);
-        c3.participate(p32);
-        c3.participate(p31); // should be "ignored"
+        c3.addParticipant(p31);
+        c3.addParticipant(p32);
+        c3.addParticipant(p31); // should be "ignored"
         assertTrue(c3.getParticipants().contains(p31));
         assertTrue(c3.getParticipants().contains(p32));
         assertEquals(2, c3.getParticipants().size());
@@ -264,26 +267,25 @@ public class CoordinatorImplTest extends
     public void test_Coordination_timeout() throws InterruptedException
     {
         final String name = "test";
-        final Coordination c1 = coordinator.create(name);
+        final Coordination c1 = coordinator.create(name, 200);
         final MockParticipant p1 = new MockParticipant();
-        c1.participate(p1);
+        c1.addParticipant(p1);
         assertTrue(c1.getParticipants().contains(p1));
         assertEquals(1, c1.getParticipants().size());
 
-        // set a short timeout and wait for it to pass
-        c1.addTimeout(100);
-        Thread.sleep(150);
+        // wait for the coordination to time out
+        Thread.sleep(250);
 
         // expect coordination to have terminated
         assertTrue(c1.isTerminated());
-        assertTrue(c1.isFailed());
+        assertSame(Coordination.TIMEOUT, c1.getFailure());
 
         // expect Participant.failed() being called
         assertTrue(p1.failed);
         assertEquals(c1, p1.c);
     }
 
-    public void test_Coordination_participate_timeout() throws InterruptedException
+    public void test_Coordination_addParticipant_timeout() throws InterruptedException
     {
         final String name1 = "test1";
         final String name2 = "test2";
@@ -292,31 +294,31 @@ public class CoordinatorImplTest extends
         // ensure short timeout for participation
         mgr.configure(60000, 200);
 
-        final Coordination c1 = coordinator.create(name1);
-        c1.participate(p1);
+        final Coordination c1 = coordinator.create(name1, 0);
+        c1.addParticipant(p1);
         assertTrue(c1.getParticipants().contains(p1));
         assertEquals(1, c1.getParticipants().size());
 
         // preset p1PartFailure to be be sure the participation actually starts
-        p1.participateFailure(new Exception("Not Started yet"));
+        p1.addParticipantFailure(new Exception("Not Started yet"));
 
         Thread c2Thread = new Thread()
         {
             public void run()
             {
-                final Coordination c2 = coordinator.create(name2);
+                final Coordination c2 = coordinator.create(name2, 0);
                 try
                 {
-                    p1.participateFailure(null);
-                    c2.participate(p1);
+                    p1.addParticipantFailure(null);
+                    c2.addParticipant(p1);
                 }
                 catch (Throwable t)
                 {
-                    p1.participateFailure(t);
+                    p1.addParticipantFailure(t);
                 }
                 finally
                 {
-                    c2.terminate();
+                    c2.end();
                 }
             }
         };
@@ -327,21 +329,21 @@ public class CoordinatorImplTest extends
         c2Thread.join(2000);
         assertFalse("Thread for second Coordination did not terminate....", c2Thread.isAlive());
 
-        Throwable p1PartFailure = p1.participateFailure;
+        Throwable p1PartFailure = p1.addParticipantFailure;
         if (p1PartFailure == null)
         {
-            fail("Expecting CoordinationException/TIMEOUT for second participation");
+            fail("Expecting CoordinationException/UNKNOWN for second participation");
         }
         else if (p1PartFailure instanceof CoordinationException)
         {
-            assertEquals(CoordinationException.TIMEOUT, ((CoordinationException) p1PartFailure).getReason());
+            assertEquals(CoordinationException.UNKNOWN, ((CoordinationException) p1PartFailure).getType());
         }
         else
         {
-            fail("Unexpected Throwable while trying to participate: " + p1PartFailure);
+            fail("Unexpected Throwable while trying to addParticipant: " + p1PartFailure);
         }
 
-        c1.terminate();
+        c1.end();
 
         // make sure c2Thread has terminated
         if (c2Thread.isAlive())
@@ -363,7 +365,7 @@ public class CoordinatorImplTest extends
 
         boolean ended;
 
-        Throwable participateFailure;
+        Throwable addParticipantFailure;
 
         public void failed(Coordination c) throws Exception
         {
@@ -379,9 +381,9 @@ public class CoordinatorImplTest extends
             this.time = System.nanoTime();
         }
 
-        void participateFailure(Throwable t)
+        void addParticipantFailure(Throwable t)
         {
-            this.participateFailure = t;
+            this.addParticipantFailure = t;
         }
     }
 }