From 196367e22e4be86f26ada428e5b2ffe117d055a5 Mon Sep 17 00:00:00 2001 From: Raymond Auge Date: Mon, 15 Jun 2015 13:26:18 -0400 Subject: [PATCH] FELIX-4931 Deadlock when running on equinox --- .../internal/DirectoryWatcher.java | 34 ++++++++++++++++--- .../internal/DirectoryWatcherTest.java | 4 ++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java index 4013dc01295..45c56be6837 100644 --- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java +++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java @@ -38,6 +38,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.jar.JarInputStream; import java.util.jar.Manifest; @@ -492,9 +497,18 @@ private void doProcess(Set files) throws InterruptedException if (toRefresh.size() > 0) { // Refresh if any bundle got uninstalled or updated. - refresh(toRefresh); + Future refresh = refresh(toRefresh); // set the state to reattempt starting managed bundles which aren't already STARTING or ACTIVE - setStateChanged(true); + + try { + // wait for the refresh to happen + refresh.get(); + setStateChanged(true); + } + catch (ExecutionException ee) { + // should never happen + ee.printStackTrace(); + } } } @@ -669,9 +683,21 @@ boolean isFragment(Bundle bundle) /** * Convenience to refresh the packages */ - void refresh(Collection bundles) throws InterruptedException + Future refresh(final Collection bundles) throws InterruptedException { - FileInstall.refresh(context, bundles); + ExecutorService executorService = Executors.newSingleThreadExecutor(); + + return executorService.submit( + new Callable() { + + public Void call() throws Exception { + FileInstall.refresh(context, bundles); + + return null; + } + + } + ); } /** diff --git a/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/DirectoryWatcherTest.java b/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/DirectoryWatcherTest.java index 0a764322cd8..3628d4cae84 100644 --- a/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/DirectoryWatcherTest.java +++ b/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/DirectoryWatcherTest.java @@ -26,6 +26,7 @@ import java.util.Hashtable; import java.util.Map; import java.util.Set; +import java.util.concurrent.Future; import junit.framework.TestCase; import org.apache.felix.fileinstall.ArtifactListener; import org.easymock.EasyMock; @@ -417,8 +418,9 @@ public Set scan(boolean reportImmediately) dw = new DirectoryWatcher(fileInstall, props, mockBundleContext) { - void refresh(Collection bundles) throws InterruptedException { + Future refresh(Collection bundles) throws InterruptedException { Assert.fail("bundle refresh called"); + return null; } };