/**
* Copyright (c) 2013 Cisco Systems, Inc. and others. 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.opendaylight.openflowplugin.openflow.md.queue;
import java.util.Collection;
import org.opendaylight.openflowplugin.api.openflow.md.queue.Enqueuer;
import org.opendaylight.openflowplugin.api.openflow.md.queue.HarvesterHandle;
import org.opendaylight.openflowplugin.api.openflow.md.queue.QueueItem;
import org.opendaylight.openflowplugin.api.openflow.md.queue.QueueKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @param <IN> Type of queue keeper harvester
*
*/
public class QueueKeeperHarvester<IN> implements Runnable, HarvesterHandle {
private static final Logger LOG = LoggerFactory.getLogger(QueueKeeperHarvester.class);
private final Collection<QueueKeeper<IN>> messageSources;
private final Enqueuer<QueueItem<IN>> enqueuer;
private final Object harvestLock = new Object();
private volatile boolean finishing = false;
private volatile boolean wakeMe = false;
/**
* @param enqueuer queue enqueuer
* @param messageSources source of message
*/
public QueueKeeperHarvester(final Enqueuer<QueueItem<IN>> enqueuer,
final Collection<QueueKeeper<IN>> messageSources) {
this.enqueuer = enqueuer;
this.messageSources = messageSources;
}
@Override
public void run() {
while (!finishing) {
boolean starving = true;
for (QueueKeeper<IN> source : messageSources) {
QueueItem<IN> qItem = source.poll();
if (qItem != null) {
starving = false;
enqueuer.enqueueQueueItem(qItem);
}
}
if (starving) {
LOG.trace("messageHarvester is about to make a starve sleep");
synchronized (harvestLock) {
wakeMe = true;
try {
this.harvestLock.wait();
LOG.trace("messageHarvester is waking up from a starve sleep");
} catch (InterruptedException e) {
LOG.warn("message harvester has been interrupted during starve sleep", e);
} finally {
wakeMe = false;
}
}
}
}
}
/**
* finish harvester
*/
public void shutdown() {
this.finishing = true;
ping();
}
@Override
public void ping() {
if (wakeMe) {
synchronized (harvestLock) {
// Might've raced while waiting for lock, so need to recheck
if (wakeMe) {
LOG.debug("pinging message harvester in starve status");
harvestLock.notify();
}
}
}
}
}