You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cs...@apache.org on 2017/10/10 15:52:10 UTC

svn commit: r1811729 - in /aries/trunk/component-dsl/component-dsl/src: main/java/org/apache/aries/osgi/functional/internal/ test/java/org/apache/aries/osgi/functional/internal/

Author: csierra
Date: Tue Oct 10 15:52:10 2017
New Revision: 1811729

URL: http://svn.apache.org/viewvc?rev=1811729&view=rev
Log:
[Component-DSL] lock free doubly linked list

With access to underlying nodes so we don't need to traverse the list or
rely on equality checks to remove items from the lists.

Removed:
    aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/DoublyLinkedList.java
    aries/trunk/component-dsl/component-dsl/src/test/java/org/apache/aries/osgi/functional/internal/DoublyLinkedListTest.java
Modified:
    aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConcurrentDoublyLinkedList.java
    aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java
    aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java

Modified: aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConcurrentDoublyLinkedList.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConcurrentDoublyLinkedList.java?rev=1811729&r1=1811728&r2=1811729&view=diff
==============================================================================
--- aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConcurrentDoublyLinkedList.java (original)
+++ aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConcurrentDoublyLinkedList.java Tue Oct 10 15:52:10 2017
@@ -209,10 +209,13 @@ public class ConcurrentDoublyLinkedList<
      * @throws NullPointerException
      *             if the specified element is <tt>null</tt>
      */
-    public void addFirst(E o) {
+    public Node addFirst(E o) {
         checkNullArg(o);
-        while (header.append(o) == null)
+        NodeImpl<E> append;
+        while ((append = header.append(o)) == null)
             ;
+
+        return append;
     }
 
     /**
@@ -224,10 +227,13 @@ public class ConcurrentDoublyLinkedList<
      * @throws NullPointerException
      *             if the specified element is <tt>null</tt>
      */
-    public void addLast(E o) {
+    public Node addLast(E o) {
         checkNullArg(o);
-        while (trailer.prepend(o) == null)
+        NodeImpl<E> append;
+        while ((append = trailer.prepend(o)) == null)
             ;
+
+        return append;
     }
 
     /**
@@ -628,6 +634,10 @@ public class ConcurrentDoublyLinkedList<
         }
     }
 
+    public interface Node {
+        public boolean remove();
+    }
+
 }
 
 
@@ -655,7 +665,9 @@ public class ConcurrentDoublyLinkedList<
  * unrecoverably stale.
  */
 
-class NodeImpl<E> extends AtomicReference<NodeImpl<E>> {
+class NodeImpl<E> extends AtomicReference<NodeImpl<E>>
+    implements ConcurrentDoublyLinkedList.Node {
+
     private volatile NodeImpl<E> prev;
 
     final E element;
@@ -674,6 +686,18 @@ class NodeImpl<E> extends AtomicReferenc
         this.element = null;
     }
 
+    @Override
+    public boolean remove() {
+        if (isDeleted()) {
+            return false;
+        }
+
+        while (!delete() && !isDeleted())
+            ;
+
+        return true;
+    }
+
     /**
      * Gets next link (which is actually the value held as atomic
      * reference).

Modified: aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java?rev=1811729&r1=1811728&r2=1811729&view=diff
==============================================================================
--- aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java (original)
+++ aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java Tue Oct 10 15:52:10 2017
@@ -19,7 +19,7 @@ package org.apache.aries.osgi.functional
 
 import org.apache.aries.osgi.functional.OSGi;
 import org.apache.aries.osgi.functional.OSGiResult;
-import org.apache.aries.osgi.functional.internal.DoublyLinkedList.Node;
+import org.apache.aries.osgi.functional.internal.ConcurrentDoublyLinkedList.Node;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
@@ -181,25 +181,22 @@ public class OSGiImpl<T> implements OSGi
 				AtomicReference<OSGiResult> otherCloseReference =
 					new AtomicReference<>();
 
-				DoublyLinkedList<Tuple<T>> identities =
-					new DoublyLinkedList<>();
+				ConcurrentDoublyLinkedList<Tuple<T>> identities =
+					new ConcurrentDoublyLinkedList<>();
 
-				DoublyLinkedList<Tuple<Function<T, S>>> funs =
-					new DoublyLinkedList<>();
+				ConcurrentDoublyLinkedList<Tuple<Function<T, S>>> funs =
+					new ConcurrentDoublyLinkedList<>();
 
 				return new OSGiResultImpl(
 					() -> {
 						OSGiResultImpl or1 = _operation.run(
 							bundleContext,
 							t -> {
-								synchronized (identities) {
-									Node<Tuple<T>> node = identities.addLast(t);
+								Node node = identities.addLast(t);
 
-									t.onTermination(node::remove);
+								t.onTermination(node::remove);
 
-									funs.forEach(
-										f -> processAdded(op, f, t));
-								}
+								funs.forEach(f -> processAdded(op, f, t));
 							}
 						);
 
@@ -209,15 +206,12 @@ public class OSGiImpl<T> implements OSGi
 							((OSGiImpl<Function<T, S>>) fun)._operation.run(
 								bundleContext,
 								f -> {
-									synchronized (identities) {
-										Node<Tuple<Function<T, S>>> node =
-											funs.addLast(f);
-
-										f.onTermination(node::remove);
-
-										identities.forEach(
-											t -> processAdded(op, f, t));
-									}
+									Node node = funs.addLast(f);
+
+									f.onTermination(node::remove);
+
+									identities.forEach(
+										t -> processAdded(op, f, t));
 								});
 
 						otherCloseReference.set(funRun);
@@ -227,11 +221,9 @@ public class OSGiImpl<T> implements OSGi
 						funRun.start();
 					},
 					() -> {
-						synchronized (identities) {
-							myCloseReference.get().close();
+						myCloseReference.get().close();
 
-							otherCloseReference.get().close();
-						}
+						otherCloseReference.get().close();
 					});
 			}
 			));

Modified: aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java?rev=1811729&r1=1811728&r2=1811729&view=diff
==============================================================================
--- aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java (original)
+++ aries/trunk/component-dsl/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java Tue Oct 10 15:52:10 2017
@@ -33,7 +33,8 @@ class Tuple<T> implements Event<T> {
 
 	public final T _t;
 	private final Deque<Runnable> _closingHandlers = new LinkedList<>();
-	private final DoublyLinkedList<Tuple<?>> _relatedTuples = new DoublyLinkedList<>();
+	private final ConcurrentDoublyLinkedList<Tuple<?>> _relatedTuples =
+		new ConcurrentDoublyLinkedList<>();
 	private volatile boolean _closed = false;
 
 	private Tuple(T t) {
@@ -47,10 +48,9 @@ class Tuple<T> implements Event<T> {
 			return;
 		}
 
-		DoublyLinkedList.Node<Tuple<?>> tupleNode = _relatedTuples.addLast(
-			tuple);
+		ConcurrentDoublyLinkedList.Node node = _relatedTuples.addLast(tuple);
 
-		tuple.onTermination(tupleNode::remove);
+		tuple.onTermination(node::remove);
 	}
 
 	public static <T> Tuple<T> create(T t) {