blob: ec9dfab534ca41b30eff0e993449d99fe87dacff [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2018 The University of York.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.epsilon.common.concurrent;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
/**
* Utility class which allows for co-ordinating concurrent execution with waiting
* semantics for successful and exceptional completion. This class can support multiple
* conditions to be registered, signalled and waited on.
*
* @see SingleConcurrentExecutionStatus
* @author Sina Madani
* @since 1.6
* @deprecated Not currently maintained.
*/
@Deprecated
public final class MultiConcurrentExecutionStatus extends ConcurrentExecutionStatus {
private final Map<Object, Object> results = new HashMap<>();
private final Map<Object, Thread> inProgress = ConcurrencyUtils.concurrentMap(4, 2);
@Override
public Object getResult(Object lockObj) {
return results.remove(lockObj);
}
@Override
public boolean register(Object lockObj) {
inProgress.put(lockObj, Thread.currentThread());
return true;
}
@Override
public boolean isInProgress(Object lockObj) {
return inProgress.containsKey(lockObj);
}
// SIGNAL CODE
private void complete(Object lockObj) {
Thread waitingThread = inProgress.remove(lockObj);
if (waitingThread != null) {
waitingThread.interrupt();
}
/*else {
synchronized (lockObj) {
lockObj.notify();
}
}*/
}
@Override
public void completeSuccessfully(Object lockObj) {
complete(lockObj);
}
@Override
public void completeWithResult(Object lockObj, Object result) {
results.put(lockObj, result);
complete(lockObj);
}
@Override
public void completeExceptionally(Throwable exception) {
if (completeExceptionallyBase(exception)) {
inProgress.values().forEach(Thread::interrupt);
}
}
// WAIT CODE
/**
* Waits until either exceptional or successful completion conditions are signalled.
*
* @return Whether the completion was successful (<code>true</code>) or exceptional (<code>false</code>).
*/
@Override
public boolean waitForCompletion(Object lockObj, Supplier<Boolean> targetState) {
synchronized (lockObj) {
if (isInProgress(lockObj)) {
inProgress.put(lockObj, Thread.currentThread());
}
while (isInProgress(lockObj) && (targetState == null || !targetState.get())) {
try {
lockObj.wait();
}
catch (InterruptedException ie) {
// Interrupt is desirable - no special action needed.
}
}
}
return !failed;
}
@Override
public boolean waitForCompletion(Object lockObj) {
return waitForCompletion(lockObj, null);
}
}