package ibis.ipl.registry.gossip;
import ibis.smartsockets.virtual.VirtualSocketAddress;
import ibis.util.ThreadPool;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Broadcasts the leave of an ibis
*/
final class Broadcaster implements Runnable {
private static final int THREADS = 10;
private static final Logger logger = LoggerFactory.getLogger(Broadcaster.class);
private final CommunicationHandler commHandler;
private List<VirtualSocketAddress> q;
private int count;
Broadcaster(CommunicationHandler commHandler,
VirtualSocketAddress[] addresses) {
this.commHandler = commHandler;
// Arrays.asList list does not support remove, so do this "trick"
q = new LinkedList<VirtualSocketAddress>();
q.addAll(Arrays.asList(addresses));
// number of jobs remaining
count = this.q.size();
int threads = Math.min(THREADS, count);
for (int i = 0; i < threads; i++) {
ThreadPool.createNew(this, "broadcaster");
}
}
synchronized VirtualSocketAddress next() {
if (q.isEmpty()) {
return null;
}
return q.remove(0);
}
synchronized void doneJob() {
count--;
if (count <= 0) {
notifyAll();
}
}
synchronized void waitUntilDone() {
logger.debug("waiting until done, " + count + " remaining");
while (count > 0) {
try {
wait();
} catch (InterruptedException e) {
// IGNORE
}
}
logger.debug("done!");
}
public void run() {
while (true) {
VirtualSocketAddress address = next();
if (address == null) {
// done pushing
return;
}
logger.trace("sending leave to " + address);
commHandler.sendLeave(address);
doneJob();
}
}
}