package io.cattle.platform.lock.provider.impl;
import io.cattle.platform.lock.Lock;
import io.cattle.platform.lock.definition.LockDefinition;
import io.cattle.platform.lock.provider.LockProvider;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractStandardLockProvider implements LockProvider {
private static final Logger log = LoggerFactory.getLogger(AbstractStandardLockProvider.class);
Map<String, StandardLock> locks = new HashMap<String, StandardLock>();
boolean referenceCountLocks = true;
@Override
public String getName() {
return getClass().getSimpleName();
}
@Override
public synchronized Lock getLock(LockDefinition lockDefinition) {
if (lockDefinition == null || lockDefinition.getLockId() == null)
return null;
if (!referenceCountLocks) {
return createLock(lockDefinition);
}
StandardLock lock = locks.get(lockDefinition.getLockId());
if (lock == null) {
lock = createLock(lockDefinition);
locks.put(lockDefinition.getLockId(), lock);
}
lock.incrementReference();
return lock;
}
protected abstract StandardLock createLock(LockDefinition lockDefinition);
@Override
public synchronized void releaseLock(Lock lock) {
if (lock instanceof StandardLock) {
StandardLock sLock = (StandardLock) lock;
if (!referenceCountLocks) {
destroyLock(sLock);
return;
}
long count = sLock.decrementReference();
if (count <= 0) {
destroyLock(sLock);
locks.remove(lock.getLockDefinition().getLockId());
if (count < 0) {
log.error("Reference count is not zero this should not happened and it is a bug, count [{}]", count);
}
}
} else {
throw new IllegalStateException("Lock [" + lock + "] not created by this provider");
}
}
protected void destroyLock(StandardLock lock) {
}
public boolean isReferenceCountLocks() {
return referenceCountLocks;
}
public void setReferenceCountLocks(boolean referenceCountLocks) {
this.referenceCountLocks = referenceCountLocks;
}
}