package org.red5.server.plugin.icy; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.red5.logging.Red5LoggerFactory; import org.red5.server.plugin.icy.stream.NSVConsumer; import org.slf4j.Logger; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * Provides a means to manage streams and threads. * * @author Paul Gregoire (mondain@gmail.com) */ public class StreamManager implements InitializingBean, DisposableBean { private static Logger log = Red5LoggerFactory.getLogger(StreamManager.class, "plugins"); //executor thread pool size private int poolSize = 1; private static ExecutorService executor; private static final Set<NSVConsumer> consumers = new HashSet<NSVConsumer>(); @Override public void afterPropertiesSet() throws Exception { executor = Executors.newFixedThreadPool(poolSize); } @Override public void destroy() throws Exception { //clear the set consumers.clear(); //disable new tasks from being submitted executor.shutdown(); try { //wait a while for existing tasks to terminate if (!executor.awaitTermination(3, TimeUnit.SECONDS)) { executor.shutdownNow(); // cancel currently executing tasks //wait a while for tasks to respond to being canceled if (!executor.awaitTermination(3, TimeUnit.SECONDS)) { System.err.println("Notifier pool did not terminate"); } } } catch (InterruptedException ie) { // re-cancel if current thread also interrupted executor.shutdownNow(); // preserve interrupt status Thread.currentThread().interrupt(); } } public void addConsumer(final NSVConsumer consumer) { log.debug("Add consumer: {}", consumer); //add consumer to collection if (consumers.add(consumer)) { Runnable initer = new Runnable() { public void run() { //start the consumer consumer.init(); } }; StreamManager.submit(initer); } } public void removeConsumer(NSVConsumer consumer) { log.debug("Remove consumer: {}", consumer); //remove it if (consumers.remove(consumer)) { consumer.stop(); } } /** * Adds a runnable to the executor service. * * @param runnable */ public static void submit(Runnable runnable) { log.debug("Submit runnable"); executor.execute(runnable); } public int getPoolSize() { return poolSize; } public void setPoolSize(int poolSize) { this.poolSize = poolSize; } }