/*******************************************************************************
* Copyright (c) 2013 Bruno Medeiros and other Contributors.
* 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
*
* Contributors:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package melnorme.utilbox.concurrency;
import java.util.concurrent.CountDownLatch;
/**
* A latchRunnable provides a two way (entry and exit) concurrency barrier.
* It is useful mostly for tests related to concurrent code.
*/
public class LatchRunnable implements Runnable, AutoCloseable {
public final CountDownLatch entryLatch = new CountDownLatch(1);
public final CountDownLatch exitLatch = new CountDownLatch(1);
public final boolean retryAwait;
public LatchRunnable() {
this(false);
}
public LatchRunnable(boolean retryAwait) {
this.retryAwait = retryAwait;
}
@Override
public void run() {
entryLatch.countDown();
while(true) {
try {
exitLatch.await();
return;
} catch (InterruptedException e) {
if(retryAwait) {
continue;
} else {
return;
}
}
}
}
public void awaitTaskEntry() throws InterruptedException {
entryLatch.await();
}
public void awaitTaskEntry_unchecked() {
try {
entryLatch.await();
} catch (InterruptedException e) {
throw melnorme.utilbox.core.ExceptionAdapter.unchecked(e);
}
}
public void releaseAll() {
entryLatch.countDown();
exitLatch.countDown();
}
@Override
public void close() {
releaseAll(); // Ensure whatever was holding on the latch is released, even for error cleanup
}
}