/*
* Copyright Terracotta, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ehcache.impl.internal.events;
import org.ehcache.core.spi.store.events.StoreEvent;
import org.ehcache.core.spi.store.events.StoreEventListener;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
FireableStoreEventHolder
/**
* FireableStoreEventHolder
*/
class FireableStoreEventHolder<K, V> {
enum Status {
CREATED, FIREABLE, FIRED
}
private final Lock lock = new ReentrantLock();
private final AtomicReference<Status> status = new AtomicReference<>(Status.CREATED);
private volatile boolean failed = false;
private final StoreEvent<K, V> event;
private final Condition condition;
FireableStoreEventHolder(StoreEvent<K, V> event) {
this.event = event;
this.condition = lock.newCondition();
}
void markFireable() {
status.compareAndSet(Status.CREATED, Status.FIREABLE);
}
boolean isFireable() {
return status.get().equals(Status.FIREABLE);
}
void waitTillFired() {
while (!isFired()) {
lock.lock();
try {
if (!isFired()) {
condition.awaitUninterruptibly();
}
} finally {
lock.unlock();
}
}
}
private boolean isFired() {
return status.get() == Status.FIRED;
}
boolean markFired() {
boolean didIt = status.compareAndSet(Status.FIREABLE, Status.FIRED);
if (didIt) {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
return didIt;
}
void markFailed() {
failed = true;
}
void fireOn(StoreEventListener<K, V> listener) {
if (!failed) {
listener.onEvent(event);
}
}
int eventKeyHash() {
return event.getKey().hashCode();
}
StoreEvent<K, V> getEvent() {
return event;
}
@Override
public String toString() {
return "FireableStoreEventHolder in state " + status.get() + " of " + event + (failed ? " (failed)":" (not failed)");
}
}