/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.rfxcom.internal;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.openhab.binding.rfxcom.internal.messages.RFXComTransmitterMessage;
/**
* The Response of a Command is always a {@link RFXComTransmitterMessage}. This implements
* a very simple {@link Future} for that type.
*
* @author Jürgen Richtsfeld
* @since 1.7
*/
class RFXComResponse implements Future<RFXComTransmitterMessage> {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private RFXComTransmitterMessage result = null;
private boolean done = false;
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
lock.lock();
try {
return done;
} finally {
lock.unlock();
}
}
@Override
public RFXComTransmitterMessage get() throws InterruptedException, ExecutionException {
lock.lock();
try {
if (!done) {
condition.await();
}
return result;
} finally {
lock.unlock();
}
}
@Override
public RFXComTransmitterMessage get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
lock.lock();
try {
if (!done) {
final boolean timedOut = !condition.await(timeout, unit);
if (timedOut) {
throw new TimeoutException("waiting timed out");
}
}
return result;
} finally {
lock.unlock();
}
}
public void set(final RFXComTransmitterMessage result) {
lock.lock();
try {
this.result = result;
this.done = true;
condition.signalAll();
} finally {
lock.unlock();
}
}
}