view rep/channel/SelectorSimulator.java @ 308:c5be84d53c7f channel-simulator-update **INVALID**

*** empty log message ***
author kono
date Sat, 04 Oct 2008 22:12:34 +0900
parents cf9328e66d25
children edb373aa421e
line wrap: on
line source

package rep.channel;

import java.io.IOException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SelectorSimulator<P> extends REPSelector<P>{

	// access to these set have to be synchronized
	private Set<SelectionKey> keyList;
	private Set<SelectionKey> selectedKeys;

	public SelectorSimulator() {
		super(null);
		keyList = new HashSet<SelectionKey>();
	}

	public synchronized int select() throws IOException {
		while(true) {
			getSelectedKeys();
			if(selectedKeys.isEmpty()) {
				try {
					this.wait();
				} catch (InterruptedException e) {
					throw new IOException("Error, Selector was interrupted!");
				}
			} else
				break;
		}
		return selectedKeys.size();
	}

	@Override
	public synchronized int select(long timeout) throws IOException {
		getSelectedKeys();
		if(selectedKeys.isEmpty()) {
			try {
				this.wait(timeout);
				// we cannot know if we timeouted or not
				getSelectedKeys(); 
			} catch (InterruptedException e) {
				throw new IOException("Error, Selector was interrupted!");
			}
		} 
		return selectedKeys.size();
	}

	private void getSelectedKeys() {
		selectedKeys = new HashSet<SelectionKey>();
		for(SelectionKey key : keyList){
			if(((SelectionKeySimulator<?>) key).isAble())
				selectedKeys.add(key);
		}
	}

	@Override
	public synchronized int selectNow() throws IOException {
		getSelectedKeys();
		return selectedKeys.size();
	}

	public SelectionKeySimulator<P> register(SelectableChannel cs, int opt){
		return register(cs, opt, null);
	}
	public SelectionKeySimulator<P> register(SelectableChannel cs, int opt, Object handler){
		SelectionKeySimulator<P> key = new SelectionKeySimulator<P>(cs, opt, this);
		key.attach(handler);
		synchronized(this) {
			keyList.add(key);
		}
		return key;
	}

	public synchronized void deregister(SelectableChannel channel) {
		for(Iterator<SelectionKey> it = keyList.iterator();it.hasNext();) {
			if(it.next().channel() == channel)
				it.remove();
		}
	}


	public synchronized Set<REPSelectionKey<P>> selectedKeys1() {
		Set<SelectionKey> keys = keyList;
		Set<REPSelectionKey<P>> newKeys = new HashSet<REPSelectionKey<P>>();
		for(SelectionKey k: keys) {
			// REPSelectionKeyを生成しないように注意
			newKeys.add(new SelectionKeySimulator<P>(k));
		}
		return newKeys;//(Set<REPSelectionKey<P>>)newKeys;
	}

	public synchronized <T> SelectionKey getKey(ChannelSimulator<T> channel){
		for(SelectionKey key : keyList){
			if(key.channel() == channel)
				return key;
		}
		return null;
	}

	@Override
	public void close() throws IOException {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isOpen() {
		return true;
	}

	@Override
	public Set<SelectionKey> keys() {
		return keyList;
	}

	@Override
	public SelectorProvider provider() {
		// TODO Auto-generated method stub
		return null;
	}


	@Override
	public synchronized Selector wakeup() {
		notifyAll();
		return this;
	}

	@Override
	public synchronized Set<SelectionKey> selectedKeys() {
		return (Set<SelectionKey>)selectedKeys;
	}

}