Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java44
1 files changed, 31 insertions, 13 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java
index d36fefbf4..c692402bb 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java
@@ -14,7 +14,10 @@ package org.eclipse.osgi.storage.bundlefile;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.osgi.framework.eventmgr.EventDispatcher;
import org.eclipse.osgi.framework.eventmgr.EventManager;
import org.eclipse.osgi.framework.eventmgr.ListenerQueue;
@@ -35,7 +38,6 @@ public class MRUBundleFileList implements EventDispatcher<Object, Object, Bundle
final private long[] useStampList;
// the limit of open files to allow before least used bundle file is closed
final private int fileLimit; // value < MIN will disable MRU
- final private int delayLimit;
private EventManager bundleFileCloserManager = null;
final private Map<Object, Object> bundleFileCloser;
// the current number of open bundle files
@@ -45,14 +47,13 @@ public class MRUBundleFileList implements EventDispatcher<Object, Object, Bundle
// used to work around bug 275166
private boolean firstDispatch = true;
- private AtomicInteger pending = new AtomicInteger();
+ private final ReentrantLock pendingLock = new ReentrantLock();
+ private final Condition pendingCond = pendingLock.newCondition();
+ private final AtomicInteger pending = new AtomicInteger();
public MRUBundleFileList(int fileLimit) {
// only enable the MRU if the initFileLimit is > MIN
this.fileLimit = fileLimit;
- // If the filelimit is > 5000 then use it as the delayLimit also;
- // Otherwise use the max between fileLimit * 2 and 500
- this.delayLimit = Math.max(fileLimit > 5000 ? fileLimit : fileLimit * 2, 500);
if (fileLimit >= MIN) {
this.bundleFileList = new BundleFile[fileLimit];
this.useStampList = new long[fileLimit];
@@ -182,21 +183,38 @@ public class MRUBundleFileList implements EventDispatcher<Object, Object, Bundle
// TODO should log ??
} finally {
closingBundleFile.set(null);
- pending.decrementAndGet();
+ pendingLock.lock();
+ try {
+ if (pending.decrementAndGet() < fileLimit) {
+ pendingCond.signalAll();
+ }
+ } finally {
+ pendingLock.unlock();
+ }
}
}
private void closeBundleFile(BundleFile toRemove, EventManager manager) {
if (toRemove == null)
return;
- int pendingNum = pending.incrementAndGet();
- if (pendingNum > delayLimit) {
- // delay to allow the closer to catchup
- try {
- Thread.sleep(Math.min(500, pendingNum));
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
+ pendingLock.lock();
+ try {
+ int pendingNum = pending.incrementAndGet();
+ if (pendingNum > fileLimit) {
+ // decrement before waiting since we will not pend until the queue
+ // reduces a bit
+ pending.decrementAndGet();
+ // delay to allow the closer to catchup
+ try {
+ pendingCond.await(Math.min(500, pendingNum), TimeUnit.MILLISECONDS);
+ // add to the pending count again
+ pending.incrementAndGet();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
}
+ } finally {
+ pendingLock.unlock();
}
try {
/* queue to hold set of listeners */

Back to the top