You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2013/12/23 15:25:23 UTC

svn commit: r1553117 - in /felix/trunk/coordinator: ./ src/main/java/org/apache/felix/coordinator/impl/ src/test/java/org/apache/felix/coordinator/impl/

Author: cziegeler
Date: Mon Dec 23 14:25:22 2013
New Revision: 1553117

URL: http://svn.apache.org/r1553117
Log:
FELIX-2647 : Implement Coordinator Service - reimplement orphaned coordination handling - passing CT now

Added:
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java   (with props)
Modified:
    felix/trunk/coordinator/pom.xml
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
    felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java

Modified: felix/trunk/coordinator/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/pom.xml?rev=1553117&r1=1553116&r2=1553117&view=diff
==============================================================================
--- felix/trunk/coordinator/pom.xml (original)
+++ felix/trunk/coordinator/pom.xml Mon Dec 23 14:25:22 2013
@@ -53,13 +53,6 @@
                             <placement>a</placement>
                             <head>ThreadSafe</head>
                         </tag>
-                        <tag>
-                            <name>Provisional</name>
-                            <placement>a</placement>
-                            <head>
-                                This is provisional API derived from OSGi R4.3 DRAFT 2 specification. This API is provided for testing purposes and gaining experience. As such this API is subject to change and will be removed once the OSGi R4.3 specification is finalized.
-                            </head>
-                        </tag>
                     </tags>
                 </configuration>
             </plugin>
@@ -100,11 +93,6 @@
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-            <version>4.3.0</version>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
             <artifactId>org.osgi.enterprise</artifactId>
             <version>5.0.0</version>
         </dependency>

Added: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java?rev=1553117&view=auto
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java (added)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java Mon Dec 23 14:25:22 2013
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * 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
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.coordinator.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.Participant;
+
+/**
+ * This is a simple wrapper around a {@link CoordinationImpl} to handle
+ * orphaned coordinations.
+ * While clients of the coordinator service get a holder object,
+ * all internal classes hold the real coordination impl instead.
+ * Therefore if no clients holds a reference to a holder anymore
+ * we can assume that the coordination is orphaned and remove it.
+ */
+public class CoordinationHolder implements Coordination {
+
+    private final CoordinationImpl coordination;
+
+	public CoordinationHolder(final CoordinationImpl coordination) {
+		this.coordination = coordination;
+	}
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#addParticipant(org.osgi.service.coordinator.Participant)
+     */
+    public void addParticipant(final Participant participant) {
+        coordination.addParticipant(participant);
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#end()
+     */
+    public void end() {
+        coordination.end();
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#extendTimeout(long)
+     */
+    public long extendTimeout(final long timeMillis) {
+        return coordination.extendTimeout(timeMillis);
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#fail(java.lang.Throwable)
+     */
+    public boolean fail(final Throwable cause) {
+        return coordination.fail(cause);
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#getBundle()
+     */
+    public Bundle getBundle() {
+        return coordination.getBundle();
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#getEnclosingCoordination()
+     */
+    public Coordination getEnclosingCoordination() {
+        return coordination.getEnclosingCoordination();
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#getFailure()
+     */
+    public Throwable getFailure() {
+        return coordination.getFailure();
+    }
+
+	/**
+	 * @see org.osgi.service.coordinator.Coordination#getId()
+	 */
+	public long getId() {
+		return coordination.getId();
+	}
+
+    /**
+	 * @see org.osgi.service.coordinator.Coordination#getName()
+	 */
+	public String getName() {
+		return coordination.getName();
+	}
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#getParticipants()
+     */
+    public List<Participant> getParticipants() {
+        return coordination.getParticipants();
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#getThread()
+     */
+    public Thread getThread() {
+        return coordination.getThread();
+    }
+
+    /**
+     * @see org.osgi.service.coordinator.Coordination#getVariables()
+     */
+    public Map<Class<?>, Object> getVariables() {
+        return coordination.getVariables();
+    }
+
+    /**
+	 * @see org.osgi.service.coordinator.Coordination#isTerminated()
+	 */
+	public boolean isTerminated() {
+		return coordination.isTerminated();
+	}
+
+    /**
+	 * @see org.osgi.service.coordinator.Coordination#join(long)
+	 */
+	public void join(final long timeMillis) throws InterruptedException {
+		coordination.join(timeMillis);
+	}
+
+    /**
+	 * @see org.osgi.service.coordinator.Coordination#push()
+	 */
+	public Coordination push() {
+	     coordination.push();
+	     return this;
+	}
+
+	@Override
+    public boolean equals(final Object object) {
+		if ( object instanceof CoordinationImpl )
+		{
+		    return coordination.equals(object);
+		}
+		if (!(object instanceof CoordinationHolder))
+		{
+			return false;
+		}
+		return coordination.equals(((CoordinationHolder)object).coordination);
+	}
+
+	@Override
+	public int hashCode() {
+		return coordination.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return coordination.toString();
+	}
+
+    @Override
+    protected void finalize() throws Throwable {
+        if ( !this.coordination.isTerminated() )
+        {
+            this.coordination.fail(Coordination.ORPHANED);
+        }
+        super.finalize();
+    }
+
+    public Coordination getCoordination() {
+        return this.coordination;
+    }
+}

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

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationHolder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java?rev=1553117&r1=1553116&r2=1553117&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java Mon Dec 23 14:25:22 2013
@@ -417,7 +417,12 @@ public class CoordinationImpl implements
      */
     public Coordination getEnclosingCoordination()
     {
-        return this.owner.getEnclosingCoordination(this);
+        Coordination c = this.owner.getEnclosingCoordination(this);
+        if ( c != null )
+        {
+            c = new CoordinationHolder((CoordinationImpl)c);
+        }
+        return c;
     }
 
     //-------
@@ -501,29 +506,19 @@ public class CoordinationImpl implements
 	@Override
 	public boolean equals(final Object obj)
 	{
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
+		if (obj instanceof CoordinationHolder )
+		{
+		    return obj.equals(this);
+		}
+        if ( !(obj instanceof CoordinationImpl) )
+        {
 			return false;
+        }
 		final CoordinationImpl other = (CoordinationImpl) obj;
-		if (id != other.id)
-			return false;
-		return true;
+		return id == other.id;
 	}
 
 	void setAssociatedThread(final Thread t) {
 	    this.associatedThread = t;
 	}
-
-    @Override
-    protected void finalize() throws Throwable {
-        if ( !this.isTerminated() )
-        {
-            this.fail(Coordination.ORPHANED);
-        }
-        super.finalize();
-    }
-
 }

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java?rev=1553117&r1=1553116&r2=1553117&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java Mon Dec 23 14:25:22 2013
@@ -19,7 +19,6 @@
 package org.apache.felix.coordinator.impl;
 
 import java.io.IOException;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
@@ -61,9 +60,9 @@ public class CoordinationMgr implements 
 
     private final AtomicLong ctr;
 
-    private final Map<Long, WeakReference<CoordinationImpl>> coordinations;
+    private final Map<Long, CoordinationImpl> coordinations;
 
-    private final Map<Participant, WeakReference<CoordinationImpl>> participants;
+    private final Map<Participant, CoordinationImpl> participants;
 
     private final Timer coordinationTimer;
 
@@ -86,8 +85,8 @@ public class CoordinationMgr implements 
     {
         perThreadStack = new ThreadLocal<Stack<CoordinationImpl>>();
         ctr = new AtomicLong(-1);
-        coordinations = new HashMap<Long, WeakReference<CoordinationImpl>>();
-        participants = new IdentityHashMap<Participant, WeakReference<CoordinationImpl>>();
+        coordinations = new HashMap<Long, CoordinationImpl>();
+        participants = new IdentityHashMap<Participant, CoordinationImpl>();
         coordinationTimer = new Timer("Coordination Timer", true);
     }
 
@@ -98,15 +97,14 @@ public class CoordinationMgr implements 
         coordinationTimer.cancel();
 
         // terminate all active coordinations
-        final List<WeakReference<CoordinationImpl>> refs = new ArrayList<WeakReference<CoordinationImpl>>();
+        final List<CoordinationImpl> coords = new ArrayList<CoordinationImpl>();
         synchronized ( this.coordinations ) {
-            refs.addAll(this.coordinations.values());
+            coords.addAll(this.coordinations.values());
             this.coordinations.clear();
         }
-        for(final WeakReference<CoordinationImpl> r : refs)
+        for(final CoordinationImpl c : coords)
         {
-            final Coordination c = r.get();
-            if ( c != null && !c.isTerminated() )
+            if ( !c.isTerminated() )
             {
                 c.fail(Coordination.RELEASED);
             }
@@ -163,16 +161,7 @@ public class CoordinationMgr implements 
             long cutOff = System.currentTimeMillis() + participationTimeOut;
             long waitTime = (participationTimeOut > 500) ? participationTimeOut / 500 : participationTimeOut;
             // TODO - the above wait time looks wrong e.g. if it's 800, the wait time 1ms
-            WeakReference<CoordinationImpl> currentRef = participants.get(p);
-            CoordinationImpl current = null;
-            if ( currentRef != null )
-            {
-                current = currentRef.get();
-                if ( current == null )
-                {
-                    participants.remove(p);
-                }
-            }
+            CoordinationImpl current = participants.get(p);
             while (current != null && current != c)
             {
                 if (current.getThread() != null && current.getThread() == c.getThread())
@@ -201,20 +190,11 @@ public class CoordinationMgr implements 
                 }
 
                 // check again
-                current = null;
-                currentRef = participants.get(p);
-                if ( currentRef != null )
-                {
-                    current = currentRef.get();
-                    if ( current == null )
-                    {
-                        participants.remove(p);
-                    }
-                }
+                current = participants.get(p);
             }
 
             // lock participant into coordination
-            participants.put(p, new WeakReference<CoordinationImpl>(c));
+            participants.put(p, c);
         }
     }
 
@@ -229,13 +209,13 @@ public class CoordinationMgr implements 
 
     // ---------- Coordinator back end implementation
 
-    Coordination create(final CoordinatorImpl owner, final String name, final long timeout)
+    CoordinationImpl create(final CoordinatorImpl owner, final String name, final long timeout)
     {
         final long id = ctr.incrementAndGet();
         final CoordinationImpl c = new CoordinationImpl(owner, id, name, timeout);
         synchronized ( this.coordinations )
         {
-            coordinations.put(id, new WeakReference<CoordinationImpl>(c));
+            coordinations.put(id, c);
         }
         return c;
     }
@@ -299,13 +279,9 @@ public class CoordinationMgr implements 
         final ArrayList<Coordination> result = new ArrayList<Coordination>();
         synchronized ( this.coordinations )
         {
-            for(final WeakReference<CoordinationImpl> ref : this.coordinations.values() )
+            for(final CoordinationImpl c : this.coordinations.values() )
             {
-                final CoordinationImpl c = ref.get();
-                if ( c != null )
-                {
-                    result.add(c);
-                }
+                result.add(new CoordinationHolder(c));
             }
         }
         return result;
@@ -315,8 +291,7 @@ public class CoordinationMgr implements 
     {
         synchronized ( this.coordinations )
         {
-            final WeakReference<CoordinationImpl> ref = coordinations.get(id);
-            final CoordinationImpl c = (ref == null) ? null : ref.get();
+            final CoordinationImpl c = coordinations.get(id);
             return (c == null || c.isTerminated()) ? null : c;
         }
     }
@@ -447,12 +422,12 @@ public class CoordinationMgr implements 
         final List<CoordinationImpl> candidates = new ArrayList<CoordinationImpl>();
         synchronized ( this.coordinations )
         {
-            final Iterator<Map.Entry<Long, WeakReference<CoordinationImpl>>> iter = this.coordinations.entrySet().iterator();
+            final Iterator<Map.Entry<Long, CoordinationImpl>> iter = this.coordinations.entrySet().iterator();
             while ( iter.hasNext() )
             {
-                final Map.Entry<Long, WeakReference<CoordinationImpl>> entry = iter.next();
-                final CoordinationImpl c = entry.getValue().get();
-                if ( c != null && c.getBundle().getBundleId() == owner.getBundleId() )
+                final Map.Entry<Long, CoordinationImpl> entry = iter.next();
+                final CoordinationImpl c = entry.getValue();
+                if ( c.getBundle().getBundleId() == owner.getBundleId() )
                 {
                     candidates.add(c);
                 }

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java?rev=1553117&r1=1553116&r2=1553117&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java (original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java Mon Dec 23 14:25:22 2013
@@ -150,9 +150,9 @@ public class CoordinatorImpl implements 
     	}
 
     	// create coordination
-        final Coordination c = mgr.create(this, name, timeout);
+        final CoordinationImpl c = mgr.create(this, name, timeout);
 
-        return c;
+        return new CoordinationHolder(c);
     }
 
     /**
@@ -170,7 +170,7 @@ public class CoordinatorImpl implements 
     public boolean fail(final Throwable reason)
     {
         // TODO: check permission
-        CoordinationImpl current = (CoordinationImpl) peek();
+        CoordinationImpl current = (CoordinationImpl)mgr.peek();
         if (current != null)
         {
             return current.fail(reason);
@@ -184,18 +184,32 @@ public class CoordinatorImpl implements 
     public Coordination peek()
     {
         // TODO: check permission
-        return mgr.peek();
+        Coordination c = mgr.peek();
+        if ( c != null )
+        {
+            c = new CoordinationHolder((CoordinationImpl)c);
+        }
+        return c;
     }
 
     /**
      * @see org.osgi.service.coordinator.Coordinator#begin(java.lang.String, long)
      */
-    public Coordination begin(final String name, final long timeoutInMillis)
+    public Coordination begin(final String name, final long timeout)
     {
-        // TODO: check permission
-        final Coordination c = create(name, timeoutInMillis);
-        this.mgr.push((CoordinationImpl)c);
-        return c;
+        this.checkPermission(name, CoordinationPermission.INITIATE);
+
+        // check arguments
+        checkName(name);
+        if ( timeout < 0 )
+        {
+            throw new IllegalArgumentException("Timeout must not be negative");
+        }
+
+        // create coordination
+        final CoordinationImpl c = mgr.create(this, name, timeout);
+        this.mgr.push(c);
+        return new CoordinationHolder(c);
     }
 
     /**
@@ -204,13 +218,18 @@ public class CoordinatorImpl implements 
     public Coordination pop()
     {
         // TODO: check permission
-        return mgr.pop();
+        Coordination c = mgr.pop();
+        if ( c != null )
+        {
+            c = new CoordinationHolder((CoordinationImpl)c);
+        }
+        return c;
     }
 
     /**
      * @see org.osgi.service.coordinator.Coordinator#addParticipant(org.osgi.service.coordinator.Participant)
      */
-    public boolean addParticipant(Participant participant)
+    public boolean addParticipant(final Participant participant)
     {
         // TODO: check permission
         Coordination current = peek();
@@ -228,7 +247,12 @@ public class CoordinatorImpl implements 
     public Coordination getCoordination(final long id)
     {
         // TODO: check permission
-        return mgr.getCoordinationById(id);
+        Coordination c = mgr.getCoordinationById(id);
+        if ( c != null )
+        {
+            c = new CoordinationHolder((CoordinationImpl)c);
+        }
+        return c;
     }
 
     //----------

Modified: felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java?rev=1553117&r1=1553116&r2=1553117&view=diff
==============================================================================
--- felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java (original)
+++ felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java Mon Dec 23 14:25:22 2013
@@ -106,7 +106,7 @@ public class CoordinatorImplTest extends
         assertEquals(c1, coordinator.pop());
 
         assertNull(coordinator.peek());
-        coordinator.push((CoordinationImpl)c1);
+        c1.push();
         assertEquals(c1, coordinator.peek());
 
         c1.end();