/**
 * Copyright (c) 2016-2020 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 com.zsmartsystems.zigbee.transaction;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.zsmartsystems.zigbee.CommandResult;
import com.zsmartsystems.zigbee.ZigBeeStatus;

/**
 * Future implementation for asynchronous transactions. Multiple threads may listen for the completion of the
 * transaction.
 *
 * @author Chris Jackson
 */
public class ZigBeeTransactionFuture implements Future<CommandResult> {
    /**
     * The {@link CommandResult}
     */
    private CommandResult result;

    private boolean cancelled = false;

    // Not final for tests
    private static long TIMEOUT_MILLISECONDS = 12000;

    /**
     * Sets the {@link CommandResult}.
     *
     * @param result the {@link CommandResult}
     */
    public synchronized void set(final CommandResult result) {
        this.result = result;
        notifyAll();
    }

    @Override
    public synchronized boolean cancel(boolean mayInterruptIfRunning) {
        if (result != null || cancelled) {
            return false;
        }
        cancelled = true;
        notifyAll();
        return true;
    }

    @Override
    public boolean isCancelled() {
        return cancelled;
    }

    @Override
    public synchronized boolean isDone() {
        return cancelled | result != null;
    }

    @Override
    public CommandResult get() throws InterruptedException, ExecutionException {
        try {
            return get(TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            set(new CommandResult(ZigBeeStatus.FAILURE, null));
            return result;
        }
    }

    @Override
    public CommandResult get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException {
        synchronized (this) {
            if (result != null) {
                return result;
            }
            unit.timedWait(this, timeout);
            if (result == null) {
                set(new CommandResult(ZigBeeStatus.FAILURE, null));
            }
            return result;
        }
    }
}

@@ -933,16 +933,174 @@
 false;%0A%0A
+    /**%0A     * We set the timeout to 5 minutes to be long enough to allow the transaction manager to complete its queuing and%0A     * eventual retries%0A     */%0A
     // N
@@ -1156,26 +1156,17 @@
 T_MI
-LLISECONDS = 12000
+NUTES = 5
 ;%0A%0A 
@@ -1965,25 +1965,20 @@
 MEOUT_MI
-LLISECOND
+NUTE
 S, TimeU
@@ -1987,17 +1987,12 @@
 t.MI
-LLISECOND
+NUTE
 S);%0A

Increase the default timeout for transaction futures (#1110)