karaf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ggrzy...@apache.org
Subject [karaf] branch master updated: [KARAF-6089] Prevent deadlock on bundle lock between FelixStartLevel and features threads
Date Fri, 18 Jan 2019 11:53:17 GMT
This is an automated email from the ASF dual-hosted git repository.

ggrzybek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/master by this push:
     new 1e67837  [KARAF-6089] Prevent deadlock on bundle lock between FelixStartLevel and
features threads
     new cbf9755  Merge pull request #729 from grgrzybek/KARAF-6089
1e67837 is described below

commit 1e678373a99d2635493f74fa940b757ce2138f70
Author: Grzegorz Grzybek <gr.grzybek@gmail.com>
AuthorDate: Fri Jan 18 11:23:15 2019 +0100

    [KARAF-6089] Prevent deadlock on bundle lock between FelixStartLevel and features threads
---
 .../internal/service/FeaturesServiceImpl.java      | 32 ++++++++++++++++++++--
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index dcd15d8..066f721 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -45,6 +45,7 @@ import java.util.TreeSet;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -916,7 +917,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
             saveState();
             stateCopy = state.copy();
         }
-        doProvisionInThread(requirements, emptyMap(), stateCopy, getFeaturesById(), options);
+        doProvisionInThread(requirements, emptyMap(), stateCopy, getFeaturesById(), options,
false);
     }
 
     @Override
@@ -964,13 +965,38 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
                                     final State state,
                                     final Map<String, Feature> featureById,
                                     final EnumSet<Option> options) throws Exception
{
+        doProvisionInThread(requirements, stateChanges, state, featureById, options, true);
+    }
+
+    /**
+     * Actual deployment needs to be done in a separate thread.
+     * The reason is that if the console is refreshed, the current thread which is running
+     * the command may be interrupted while waiting for the refresh to be done, leading
+     * to bundles not being started after the refresh.
+     *
+     * @param requirements the provided requirements to match.
+     * @param stateChanges the current features state.
+     * @param state the current provisioning state.
+     * @param options the provisioning options.
+     * @param wait wait for provisioning to complete
+     * @throws Exception in case of provisioning failure.
+     */
+    private void doProvisionInThread(final Map<String, Set<String>> requirements,
+                                     final Map<String, Map<String, FeatureState>>
stateChanges,
+                                     final State state,
+                                     final Map<String, Feature> featureById,
+                                     final EnumSet<Option> options,
+                                     boolean wait) throws Exception {
         try {
             final String outputFile = this.outputFile.get();
             this.outputFile.set(null);
-            executor.submit(() -> {
+            Future<Object> future = executor.submit(() -> {
                 doProvision(requirements, stateChanges, state, featureById, options, outputFile);
                 return null;
-            }).get();
+            });
+            if (wait) {
+                future.get();
+            }
         } catch (ExecutionException e) {
             Throwable t = e.getCause();
             if (t instanceof RuntimeException) {


Mime
View raw message