+++ /dev/null
-package org.openflow.example;
-
-import java.io.IOException;
-import java.nio.channels.CancelledKeyException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.Iterator;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-/***
- * Dirt simple SelectLoop for simple java controller
- */
-
-
-public class SelectLoop {
- protected SelectListener callback;
- protected boolean dontStop;
- protected Object registrationLock;
- protected int registrationRequests = 0;
- protected Queue<Object[]> registrationQueue;
- protected Selector selector;
- protected long timeout;
-
- public SelectLoop(SelectListener cb) throws IOException {
- callback = cb;
- dontStop = true;
- selector = SelectorProvider.provider().openSelector();
- registrationLock = new Object();
- registrationQueue = new ConcurrentLinkedQueue<Object[]>();
- timeout = 0;
- }
-
- /**
- * Initializes this SelectLoop
- * @param cb the callback to call when select returns
- * @param timeout the timeout value in milliseconds that select will be
- * called with
- * @throws IOException
- */
- public SelectLoop(SelectListener cb, long timeout) throws IOException {
- callback = cb;
- dontStop = true;
- selector = SelectorProvider.provider().openSelector();
- registrationLock = new Object();
- registrationQueue = new ConcurrentLinkedQueue<Object[]>();
- this.timeout = timeout;
- }
-
- public void register(SelectableChannel ch, int ops, Object arg)
- throws ClosedChannelException {
- registrationQueue.add(new Object[] {ch, ops, arg});
- }
-
- /**
- * Registers the supplied SelectableChannel with this SelectLoop. Note this
- * method blocks until registration proceeds. It is advised that
- * SelectLoop is intialized with a timeout value when using this method.
- * @param ch the channel
- * @param ops interest ops
- * @param arg argument that will be returned with the SelectListener
- * @return
- * @throws ClosedChannelException
- */
- public synchronized SelectionKey registerBlocking(SelectableChannel ch, int ops, Object arg)
- throws ClosedChannelException {
- synchronized (registrationLock) {
- registrationRequests++;
- }
- selector.wakeup();
- SelectionKey key = ch.register(selector, ops, arg);
- synchronized (registrationLock) {
- registrationRequests--;
- registrationLock.notifyAll();
- }
- return key;
- }
-
- /****
- * Main top-level IO loop this dispatches all IO events and timer events
- * together I believe this is fairly efficient
- */
- public void doLoop() throws IOException {
- int nEvents;
- processRegistrationQueue();
-
- while (dontStop) {
- nEvents = selector.select(timeout);
- if (nEvents > 0) {
- for (Iterator<SelectionKey> i = selector.selectedKeys()
- .iterator(); i.hasNext();) {
- SelectionKey sk = i.next();
- i.remove();
-
- if (!sk.isValid())
- continue;
-
- Object arg = sk.attachment();
- callback.handleEvent(sk, arg);
- }
- }
-
- if (this.registrationQueue.size() > 0)
- processRegistrationQueue();
-
- if (registrationRequests > 0) {
- synchronized (registrationLock) {
- while (registrationRequests > 0) {
- try {
- registrationLock.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- }
-
- protected void processRegistrationQueue() {
- // add any elements in queue
- for (Iterator<Object[]> it = registrationQueue.iterator(); it.hasNext();) {
- Object[] args = it.next();
- SelectableChannel ch = (SelectableChannel) args[0];
- try {
- ch.register(selector, (Integer) args[1], args[2]);
- } catch (CancelledKeyException cke) {
- continue;
- } catch (ClosedChannelException e) {
- }
- it.remove();
- }
- }
-
- /**
- * Force this select loop to return immediately and re-enter select, useful
- * for example if a new item has been added to the select loop while it
- * was already blocked.
- */
- public void wakeup() {
- if (selector != null) {
- selector.wakeup();
- }
- }
-
- /**
- * Shuts down this select loop, may return before it has fully shutdown
- */
- public void shutdown() {
- this.dontStop = false;
- wakeup();
- }
-}