Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshuyangzhou2016-07-01 22:28:49 +0000
committershuyangzhou2016-07-01 22:28:49 +0000
commit05be60b155047ed686c1074c39f41c258ac47326 (patch)
tree9f0e42434f7c06834ae871c6ed94877c67b473c8
parentf2c57904cdba0dea26889cc38cabdd4f420439dd (diff)
downloadrt.equinox.bundles-twatson/LPS-66959.tar.gz
rt.equinox.bundles-twatson/LPS-66959.tar.xz
rt.equinox.bundles-twatson/LPS-66959.zip
LPS-66959 Use ReadWriteLock to optimzie reading paths in addReference()/removeReference(), when concurrent destroy() happens in between the addReference()/removeReference() window times, upgrade to write lock to ensure proper Condition waiting.twatson/LPS-66959
Signed-off-by: shuyangzhou <shuyang.zhou@liferay.com>
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/Registration.java77
1 files changed, 61 insertions, 16 deletions
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/Registration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/Registration.java
index 0df5d73a0..4e3e612f8 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/Registration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/Registration.java
@@ -12,6 +12,11 @@
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal.registration;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.osgi.dto.DTO;
public abstract class Registration<T, D extends DTO> {
@@ -19,42 +24,82 @@ public abstract class Registration<T, D extends DTO> {
private final D d;
private final T t;
- protected int referenceCount;
+ protected final AtomicInteger referenceCount = new AtomicInteger();
public Registration(T t, D d) {
this.t = t;
this.d = d;
}
- public synchronized void addReference() {
- ++referenceCount;
+ public void addReference() {
+ readLock.lock();
+
+ try {
+ referenceCount.incrementAndGet();
+ }
+ finally {
+ readLock.unlock();
+ }
}
- public synchronized void removeReference() {
- --referenceCount;
- if (referenceCount == 0) {
- notifyAll();
+ public void removeReference() {
+ readLock.lock();
+
+ try {
+ if (referenceCount.decrementAndGet() == 0 && destroyed) {
+ readLock.unlock();
+
+ writeLock.lock();
+
+ try {
+ condition.signalAll();
+ }
+ finally {
+ writeLock.unlock();
+
+ readLock.lock();
+ }
+ }
+ }
+ finally {
+ readLock.unlock();
}
}
- public synchronized void destroy() {
+ public void destroy() {
boolean interrupted = false;
+
+ writeLock.lock();
+
+ destroyed = true;
+
try {
- while (referenceCount != 0) {
+ while (referenceCount.get() != 0) {
try {
- (new Exception()).printStackTrace();
- wait();
- } catch (InterruptedException e) {
- // wait until the servlet is inactive but save the interrupted status
+ condition.await();
+ }
+ catch (InterruptedException ie) {
interrupted = true;
}
}
- } finally {
- if (interrupted)
- Thread.currentThread().interrupt(); //restore the interrupted state
+ }
+ finally {
+ writeLock.unlock();
+
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
}
}
+ private volatile boolean destroyed;
+
+ private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+
+ private final Lock readLock = readWriteLock.readLock();
+ private final Lock writeLock = readWriteLock.writeLock();
+ private final Condition condition = writeLock.newCondition();
+
public D getD() {
return d;
}

Back to the top