view rep/channel/SelectorSimulator.java @ 430:03ab374605a6

Test program termination.
author one
date Sat, 02 Jan 2010 04:16:25 +0900
parents b8efd57faf78
children
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.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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

	// This selector cannot be shared among threads.
	
	private Map<SelectableChannel, SelectionKeySimulator<P>> keyList;
	private Set<SelectionKeySimulator<P>> selectedKeys;
	private boolean isOpen=true;

	public SelectorSimulator() {
		super(null);
		keyList = new HashMap<SelectableChannel,SelectionKeySimulator<P>>();
	}

	public int select() throws IOException {
		getSelectedKeys();
		if(selectedKeys.isEmpty()) {
			try {
				synchronized(this) {
					wait();
				}
			} catch (InterruptedException e) {
				throw new IOException();
			}
		}
		return selectedKeys.size();
	}

	@Override
	public int select(long timeout) throws IOException {
		getSelectedKeys();
		if(selectedKeys.isEmpty()) {
			try {
				synchronized(this) {
					wait(timeout);
				}
				// we cannot know if we time outed or not
				getSelectedKeys(); 
			} catch (InterruptedException e) {
				throw new IOException();
			}
		} 
		return selectedKeys.size();
	}

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

	@Override
	public 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 = keyList.get(cs);
		if (key!=null) {
			key.attach(handler);
			key.interestOps(opt);
			return key;
		}
		key = new SelectionKeySimulator<P>(cs, opt, this);
		key.attach(handler);
		keyList.put(cs,key);
		return key;
	}

	public SelectionKeySimulator<P> deregister(SelectableChannel channel) {
		SelectionKeySimulator<P> key = keyList.remove(channel);
		return key;
	}


	public SelectionKey getKey(SelectableChannel channel){
		return keyList.get(channel);
	}

	@Override
	public void close() throws IOException {
		isOpen = false;
	}

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

	@Override
	public Set<SelectionKey> keys() {
		Set<SelectionKey> newKeys = new HashSet<SelectionKey>();
		for(SelectionKey k: keyList.values()) {
			newKeys.add(k);
		}
		return newKeys;
	}
	
	public Set<REPSelectionKey<P>> keys1() {
		// we cannot solve cast, we need the same method again with different types
		Set<REPSelectionKey<P>> newKeys = new HashSet<REPSelectionKey<P>>();
		for(SelectionKeySimulator<P> k: keyList.values()) {
			newKeys.add(k);
		}
		return newKeys;
	}

	@Override
	public SelectorProvider provider() {
		// should return NetworkSimulator?
		return null;
	}


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


	public Set<REPSelectionKey<P>> selectedKeys1() {
		Set<REPSelectionKey<P>> newKeys = new HashSet<REPSelectionKey<P>>();
		for(SelectionKeySimulator<P> k: selectedKeys) {
			newKeys.add(k);
		}
		return newKeys;
	}
	
	/*
	 * type safe copy of selectedKeys1()
	 */
	@Override
	public Set<SelectionKey> selectedKeys() {
		Set<SelectionKey> newKeys = new HashSet<SelectionKey>();
		for(SelectionKeySimulator<P> k: selectedKeys) {
			newKeys.add(k);
		}
		return newKeys;
	}

}