You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2008/11/20 01:00:56 UTC

svn commit: r719134 - /felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java

Author: pauls
Date: Wed Nov 19 16:00:55 2008
New Revision: 719134

URL: http://svn.apache.org/viewvc?rev=719134&view=rev
Log:
Try to improve multi bundle locking to make sure we make multi bundle operation atomic and so are not interleaved with single bundle operations.

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=719134&r1=719133&r2=719134&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Wed Nov 19 16:00:55 2008
@@ -1951,7 +1951,7 @@
                 {
                     try
                     {
-                        refreshPackages(new Bundle[] { bundle });
+                        _refreshPackages(new FelixBundle[] { bundle });
                     }
                     catch (Exception ex)
                     {
@@ -2203,7 +2203,7 @@
         {
             try
             {
-                refreshPackages(new Bundle[] { bundle });
+                _refreshPackages(new FelixBundle[] { bundle });
             }
             catch (Exception ex)
             {
@@ -3121,10 +3121,7 @@
                 depIdx++)
             {
                 Bundle b = getBundle(Util.getBundleIdFromModuleId(dependents[depIdx].getId()));
-                if (b != null)
-                {
-                    list.add(b);
-                }
+                list.add(b);
             }
         }
 
@@ -3216,8 +3213,20 @@
 
     protected void refreshPackages(Bundle[] targets)
     {
-        // Acquire locks for all impacted bundles.
         FelixBundle[] bundles = acquireBundleRefreshLocks(targets);
+        try
+        {
+            _refreshPackages(bundles);
+        }
+        finally
+        {
+            // Always release all bundle locks.
+            releaseBundleLocks(bundles);
+        }
+    }
+    
+    protected void _refreshPackages(FelixBundle[] bundles)
+    {
         boolean restart = false;
 
         Bundle systemBundle = getBundle(0);
@@ -3258,52 +3267,43 @@
         {
             forgetUninstalledBundle(bundles[i]);
         }
-
-        try
+        // If there are targets, then refresh each one.
+        if (bundles != null)
         {
-            // If there are targets, then refresh each one.
-            if (bundles != null)
-            {
-                // At this point the map contains every bundle that has been
-                // updated and/or removed as well as all bundles that import
-                // packages from these bundles.
+            // At this point the map contains every bundle that has been
+            // updated and/or removed as well as all bundles that import
+            // packages from these bundles.
 
-                // Create refresh helpers for each bundle.
-                RefreshHelper[] helpers = new RefreshHelper[bundles.length];
-                for (int i = 0; i < bundles.length; i++)
+            // Create refresh helpers for each bundle.
+            RefreshHelper[] helpers = new RefreshHelper[bundles.length];
+            for (int i = 0; i < bundles.length; i++)
+            {
+                if (!bundles[i].getInfo().isExtension())
                 {
-                    if (!bundles[i].getInfo().isExtension())
-                    {
-                        helpers[i] = new RefreshHelper(bundles[i]);
-                    }
+                    helpers[i] = new RefreshHelper(bundles[i]);
                 }
+            }
 
-                // Stop, purge or remove, and reinitialize all bundles first.
-                for (int i = 0; i < helpers.length; i++)
+            // Stop, purge or remove, and reinitialize all bundles first.
+            for (int i = 0; i < helpers.length; i++)
+            {
+                if (helpers[i] != null)
                 {
-                    if (helpers[i] != null)
-                    {
-                        helpers[i].stop();
-                        helpers[i].purgeOrRemove();
-                        helpers[i].reinitialize();
-                    }
+                    helpers[i].stop();
+                    helpers[i].purgeOrRemove();
+                    helpers[i].reinitialize();
                 }
+            }
 
-                // Then restart all bundles that were previously running.
-                for (int i = 0; i < helpers.length; i++)
+            // Then restart all bundles that were previously running.
+            for (int i = 0; i < helpers.length; i++)
+            {
+                if (helpers[i] != null)
                 {
-                    if (helpers[i] != null)
-                    {
-                        helpers[i].restart();
-                    }
+                    helpers[i].restart();
                 }
             }
         }
-        finally
-        {
-            // Always release all bundle locks.
-            releaseBundleLocks(bundles);
-        }
 
         fireFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, this, null);
     }
@@ -4148,11 +4148,27 @@
             m_installRequestLock_Priority1.notifyAll();
         }
     }
+    
+    private long m_lockCount = 0;
+    private Thread m_lockThread = null;
 
     protected void acquireBundleLock(FelixBundle bundle)
     {
         synchronized (m_bundleLock)
         {
+            while ((m_lockCount < 0) && (m_lockThread != Thread.currentThread()))
+            {
+                try
+                {
+                    m_bundleLock.wait();
+                }
+                catch (InterruptedException e)
+                {
+                    // Ignore and just keep waiting.
+                }
+            }
+            m_lockCount++;
+
             while (!bundle.getInfo().isLockable())
             {
                 try
@@ -4172,6 +4188,18 @@
     {
         synchronized (m_bundleLock)
         {
+            while ((m_lockCount < 0) && (m_lockThread != Thread.currentThread()))
+            {
+                try
+                {
+                    m_bundleLock.wait();
+                }
+                catch (InterruptedException e)
+                {
+                    // Ignore and just keep waiting.
+                }
+            }
+            m_lockCount++;
             if (!bundle.getInfo().isLockable())
             {
                 return false;
@@ -4185,6 +4213,7 @@
     {
         synchronized (m_bundleLock)
         {
+            m_lockCount--;
             bundle.getInfo().unlock();
             m_bundleLock.notifyAll();
         }
@@ -4206,6 +4235,20 @@
 
         synchronized (m_bundleLock)
         {
+            while (m_lockCount != 0)
+            {
+                try
+                {
+                    m_bundleLock.wait();
+                }
+                catch (InterruptedException e)
+                {
+                    // Ignore
+                }
+            }
+            m_lockCount = -1;
+            m_lockThread = Thread.currentThread();
+            
             boolean success = false;
             while (!success)
             {
@@ -4285,6 +4328,20 @@
 
         synchronized (m_bundleLock)
         {
+            while (m_lockCount != 0)
+            {
+                try
+                {
+                    m_bundleLock.wait();
+                }
+                catch (InterruptedException e)
+                {
+                    // Ignore
+                }
+            }
+            m_lockCount = -1;
+            m_lockThread = Thread.currentThread();
+            
             boolean success = false;
             while (!success)
             {
@@ -4396,6 +4453,8 @@
         // Always unlock any locked bundles.
         synchronized (m_bundleLock)
         {
+            m_lockCount = 0;
+            m_lockThread = null;
             for (int i = 0; (bundles != null) && (i < bundles.length); i++)
             {
                 bundles[i].getInfo().unlock();