blob: 8e669adb6ed2447bfa1b2ccb1d0cf0293640eae8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2014 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Raymond Augé <raymond.auge@liferay.com> - Bug 436698
*******************************************************************************/
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> {
private final D d;
private final T t;
protected final AtomicInteger referenceCount = new AtomicInteger();
public Registration(T t, D d) {
this.t = t;
this.d = d;
}
public void addReference() {
readLock.lock();
try {
referenceCount.incrementAndGet();
}
finally {
readLock.unlock();
}
}
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 void destroy() {
boolean interrupted = false;
writeLock.lock();
destroyed = true;
try {
while (referenceCount.get() != 0) {
try {
condition.await();
}
catch (InterruptedException ie) {
interrupted = true;
}
}
}
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;
}
public T getT() {
return t;
}
@Override
public String toString() {
return getD().toString();
}
}