Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java')
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java39
1 files changed, 34 insertions, 5 deletions
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java
index 3edcfd956..b903583e9 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java
@@ -12,6 +12,7 @@
package org.eclipse.osgi.baseadaptor.bundlefile;
import java.io.IOException;
+import org.eclipse.osgi.framework.eventmgr.*;
/**
* A simple/quick/small implementation of an MRU (Most Recently Used) list to keep
@@ -20,7 +21,7 @@ import java.io.IOException;
* file limit.
* @since 3.2
*/
-public class MRUBundleFileList {
+public class MRUBundleFileList implements EventDispatcher {
private static final String PROP_FILE_LIMIT = "osgi.bundlefile.limit"; //$NON-NLS-1$
private static final int MIN = 10;
// list of open bundle files
@@ -33,6 +34,8 @@ public class MRUBundleFileList {
private int fileLimit = 0; // value < MIN will disable MRU
// the current number of open bundle files
private int numOpen = 0;
+ private EventManager bundleFileCloserManager;
+ private EventListeners bundleFileCloser;
public MRUBundleFileList() {
try {
@@ -54,6 +57,9 @@ public class MRUBundleFileList {
this.fileLimit = initFileLimit;
this.bundleFileList = new BundleFile[initFileLimit];
this.useStampList = new long[initFileLimit];
+ this.bundleFileCloserManager = new EventManager("Bundle File Closer"); //$NON-NLS-1$
+ this.bundleFileCloser = new EventListeners();
+ this.bundleFileCloser.addListener(this, this);
}
}
@@ -67,6 +73,7 @@ public class MRUBundleFileList {
public void add(BundleFile bundleFile) throws IOException {
if (fileLimit < MIN)
return; // MRU is disabled
+ BundleFile toRemove = null;
synchronized (bundleFileList) {
int index = 0; // default to the first slot
if (numOpen < fileLimit) {
@@ -85,9 +92,8 @@ public class MRUBundleFileList {
for (int i = 1; i < fileLimit; i++)
if (useStampList[i] < useStampList[index])
index = i;
- BundleFile toRemove = bundleFileList[index];
+ toRemove = bundleFileList[index];
remove(toRemove);
- toRemove.close();
}
// found an index to place to bundleFile to be opened
bundleFileList[index] = bundleFile;
@@ -95,6 +101,9 @@ public class MRUBundleFileList {
incUseStamp(index);
numOpen++;
}
+ // must not close the toRemove bundle file while holding the lock of another bundle file (bug 161976)
+ // This queue the bundle file for close asynchronously.
+ closeBundleFile(toRemove);
}
/**
@@ -107,7 +116,8 @@ public class MRUBundleFileList {
return false; // MRU is disabled
synchronized (bundleFileList) {
int index = bundleFile.getMruIndex();
- if ((index >= 0 || index < fileLimit) && bundleFileList[index] == bundleFile) {
+ if ((index >= 0 && index < fileLimit) && bundleFileList[index] == bundleFile) {
+ bundleFile.setMruIndex(-1);
bundleFileList[index] = null;
useStampList[index] = -1;
numOpen--;
@@ -126,7 +136,7 @@ public class MRUBundleFileList {
return; // MRU is disabled
synchronized (bundleFileList) {
int index = bundleFile.getMruIndex();
- if ((index >= 0 || index < fileLimit) && bundleFileList[index] == bundleFile)
+ if ((index >= 0 && index < fileLimit) && bundleFileList[index] == bundleFile)
incUseStamp(index);
}
}
@@ -140,4 +150,23 @@ public class MRUBundleFileList {
}
useStampList[index] = ++curUseStamp;
}
+
+ public final void dispatchEvent(Object eventListener, Object listenerObject, int eventAction, Object eventObject) {
+ try {
+ ((BundleFile) eventObject).close();
+ } catch (IOException e) {
+ // TODO should log ??
+ }
+ }
+
+ private void closeBundleFile(BundleFile toRemove) {
+ if (toRemove == null)
+ return;
+ /* queue to hold set of listeners */
+ ListenerQueue queue = new ListenerQueue(bundleFileCloserManager);
+ /* add bundle file closer to the queue */
+ queue.queueListeners(bundleFileCloser, this);
+ /* dispatch event to set of listeners */
+ queue.dispatchEventAsynchronous(0, toRemove);
+ }
}

Back to the top