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 2020/05/14 17:30:07 UTC

[aries-component-dsl] 01/03: Fix applyTo

This is an automated email from the ASF dual-hosted git repository.

csierra pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-component-dsl.git

commit 32213bd0cbb93555a3232fa6f52c99ad2af1a4b4
Author: Carlos Sierra Andrés <ca...@liferay.com>
AuthorDate: Thu May 14 18:51:14 2020 +0200

    Fix applyTo
    
    it left some terminators unclosed.
---
 .../java/org/apache/aries/component/dsl/OSGi.java  | 98 ++++++++++++----------
 1 file changed, 53 insertions(+), 45 deletions(-)

diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/OSGi.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/OSGi.java
index 0d20246..ac55128 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/OSGi.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/OSGi.java
@@ -68,15 +68,7 @@ import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.BiFunction;
@@ -496,56 +488,72 @@ public interface OSGi<T> extends OSGiRunnable<T> {
 
 	default  <S> OSGi<S> applyTo(OSGi<Function<T, S>> fun) {
 		return fromOsgiRunnable((bundleContext, op) -> {
-			ConcurrentDoublyLinkedList<T> identities =
-				new ConcurrentDoublyLinkedList<>();
+			ConcurrentDoublyLinkedList<T> identities = new ConcurrentDoublyLinkedList<>();
+			ConcurrentDoublyLinkedList<Function<T,S>> functions = new ConcurrentDoublyLinkedList<>();
+			IdentityHashMap<T, IdentityHashMap<Function<T, S>, Runnable>>
+				terminators = new IdentityHashMap<>();
 
-			ConcurrentDoublyLinkedList<Function<T, S>> funs =
-				new ConcurrentDoublyLinkedList<>();
-
-			OSGiResult myResult = run(
+			OSGiResult funRun = fun.run(
 				bundleContext,
-				t -> {
-					ConcurrentDoublyLinkedList.Node node =
-						identities.addLast(t);
+				f -> {
+					synchronized(identities) {
+						ConcurrentDoublyLinkedList.Node node = functions.addLast(f);
+
+						for (T t : identities) {
+							IdentityHashMap<Function<T, S>, Runnable> terminatorMap =
+								terminators.computeIfAbsent(
+									t, __ -> new IdentityHashMap<>());
+							terminatorMap.put(f, op.apply(f.apply(t)));
+						}
 
-					List<Runnable> terminators = funs.stream().map(
-						f -> op.apply(f.apply(t))
-					).collect(
-						Collectors.toList()
-					);
+						return () -> {
+							synchronized (identities) {
+								node.remove();
 
-					return () -> {
-						node.remove();
+								identities.forEach(t -> {
+									Runnable terminator = terminators.get(t).remove(f);
 
-						terminators.forEach(Runnable::run);
-					};
+									terminator.run();
+								});
+							}
+						};
+					}
 				}
 			);
 
-			OSGiResult funRun = fun.run(
+			OSGiResult myRun = run(
 				bundleContext,
-				f -> {
-					ConcurrentDoublyLinkedList.Node node = funs.addLast(f);
+				t -> {
+					synchronized (identities) {
+						ConcurrentDoublyLinkedList.Node node = identities.addLast(t);
+
+						for (Function<T, S> f : functions) {
+							IdentityHashMap<Function<T, S>, Runnable> terminatorMap =
+								terminators.computeIfAbsent(
+									t, __ -> new IdentityHashMap<>());
+							terminatorMap.put(f, op.apply(f.apply(t)));
+						}
 
-					List<Runnable> terminators = identities.stream().map(
-						t -> op.apply(f.apply(t))
-					).collect(
-						Collectors.toList()
-					);
+						return () -> {
+							synchronized (identities) {
+								node.remove();
 
-					return () -> {
-						node.remove();
+								functions.forEach(f -> {
+									Runnable terminator = terminators.get(t).remove(f);
 
-						terminators.forEach(Runnable::run);
-					};
-				});
+									terminator.run();
+								});
+							}
+						};
+					}
+				}
+			);
 
-			return
-				() -> {
-					myResult.close();
+			return () -> {
+				myRun.close();
 
-					funRun.close();
-				};
+				funRun.close();
+			};
 		});
 	}