FELIX-2791: Introduce a barrier to synchronize watcher threads

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1061240 13f79535-47bb-0310-9956-ffa450edef68
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 9ab5d7f..a8e21a6 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
@@ -215,6 +215,24 @@
      */
     public void run()
     {
+        // We must wait for FileInstall to complete initialisation
+        // to avoid race conditions observed in FELIX-2791
+        synchronized (FileInstall.barrier)
+        {
+            while (!FileInstall.initialized)
+            {
+                try
+                {
+                    FileInstall.barrier.wait(0);
+                }
+                catch (InterruptedException e)
+                {
+                    Thread.currentThread().interrupt();
+                    log(Logger.LOG_INFO, "Watcher for " + watchedDirectory + " exiting because of interruption.", e);
+                    return;
+                }
+            }
+        }
         log(Logger.LOG_DEBUG,
             "{" + POLL + " (ms) = " + poll + ", "
                 + DIR + " = " + watchedDirectory.getAbsolutePath() + ", "
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
index 75407c5..27f889d 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
@@ -45,6 +45,8 @@
     BundleContext context;
     Map watchers = new HashMap();
     ServiceTracker listenersTracker;
+    static boolean initialized;
+    static final Object barrier = new Object();
 
     public void start(BundleContext context) throws Exception
     {
@@ -122,6 +124,12 @@
         {
             updated("initial", ht);
         }
+        // now notify all the directory watchers to proceed
+        // We need this to avoid race conditions observed in FELIX-2791
+        synchronized (barrier) {
+            initialized = true;
+            barrier.notifyAll();
+        }
     }
 
     // Adapted for FELIX-524
@@ -141,6 +149,9 @@
 
     public void stop(BundleContext context) throws Exception
     {
+        synchronized (barrier) {
+            initialized = false;
+        }
         List /*<DirectoryWatcher>*/ toClose = new ArrayList /*<DirectoryWatcher>*/();
         synchronized (watchers)
         {