Mercurial > hg > RemoteEditor > REPSessionManager
changeset 350:59ef23ee73ad
SelectorSimulator is not thread safe now.
author | kono |
---|---|
date | Thu, 16 Oct 2008 10:19:18 +0900 |
parents | ef4afcae0c92 |
children | b8efd57faf78 |
files | rep/channel/SelectorSimulator.java |
diffstat | 1 files changed, 71 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/rep/channel/SelectorSimulator.java Thu Oct 16 01:12:34 2008 +0900 +++ b/rep/channel/SelectorSimulator.java Thu Oct 16 10:19:18 2008 +0900 @@ -5,30 +5,34 @@ 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.Iterator; +import java.util.Map; 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; + // 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 HashSet<SelectionKey>(); + keyList = new HashMap<SelectableChannel,SelectionKeySimulator<P>>(); } - public synchronized int select() throws IOException { + public int select() throws IOException { while(true) { getSelectedKeys(); if(selectedKeys.isEmpty()) { try { - this.wait(); + synchronized(this) { + wait(); + } } catch (InterruptedException e) { - throw new IOException("Error, Selector was interrupted!"); + throw new IOException(); } } else break; @@ -37,30 +41,32 @@ } @Override - public synchronized int select(long timeout) throws IOException { + public int select(long timeout) throws IOException { getSelectedKeys(); if(selectedKeys.isEmpty()) { try { - wait(timeout); + synchronized(this) { + wait(timeout); + } // we cannot know if we time outed or not getSelectedKeys(); } catch (InterruptedException e) { - throw new IOException("Error, Selector was interrupted!"); + throw new IOException(); } } return selectedKeys.size(); } private void getSelectedKeys() { - selectedKeys = new HashSet<SelectionKey>(); - for(SelectionKey key : keyList){ - if(((SelectionKeySimulator<?>) key).isAble()) - selectedKeys.add(key); + selectedKeys = new HashSet<SelectionKeySimulator<P>>(); + for(SelectionKeySimulator<P> key : keyList.values()){ + if(key.isAble()) + selectedKeys.add(new SelectionKeySimulator<P>(key)); } } @Override - public synchronized int selectNow() throws IOException { + public int selectNow() throws IOException { getSelectedKeys(); return selectedKeys.size(); } @@ -69,39 +75,26 @@ return register(cs, opt, null); } public SelectionKeySimulator<P> register(SelectableChannel cs, int opt, Object handler){ - SelectionKeySimulator<P> key = new SelectionKeySimulator<P>(cs, opt, this); + 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); - deregister(cs); - synchronized(this) { - keyList.add(key); - } + keyList.put(cs,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 SelectionKeySimulator<P> deregister(SelectableChannel channel) { + SelectionKeySimulator<P> key = keyList.remove(channel); + return key; } - 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; - } - - public synchronized <T> SelectionKey getKey(ChannelSimulator<T> channel){ - for(SelectionKey key : keyList){ - if(key.channel() == channel) - return key; - } - return null; + public SelectionKey getKey(SelectableChannel channel){ + return keyList.get(channel); } @Override @@ -116,7 +109,23 @@ @Override public Set<SelectionKey> keys() { - return keyList; + Set<SelectionKey> newKeys = new HashSet<SelectionKey>(); + for(SelectionKey k: keyList.values()) { + // REPSelectionKeyを生成しないように注意 + 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()) { + // REPSelectionKeyを生成しないように注意 + newKeys.add(k); //new SelectionKeySimulator<P>(k)); + } + return newKeys; } @Override @@ -132,9 +141,26 @@ return this; } + + public Set<REPSelectionKey<P>> selectedKeys1() { + Set<REPSelectionKey<P>> newKeys = new HashSet<REPSelectionKey<P>>(); + for(SelectionKeySimulator<P> k: selectedKeys) { + // REPSelectionKeyを生成しないように注意 + //newKeys.add(new SelectionKeySimulator<P>(k)); + newKeys.add(k); + } + return newKeys; + } + @Override - public synchronized Set<SelectionKey> selectedKeys() { - return (Set<SelectionKey>)selectedKeys; + public Set<SelectionKey> selectedKeys() { + Set<SelectionKeySimulator<P>> keys = selectedKeys; + Set<SelectionKey> newKeys = new HashSet<SelectionKey>(); + for(SelectionKeySimulator<P> k: keys) { + // REPSelectionKeyを生成しないように注意 + newKeys.add(k); // new SelectionKeySimulator<P>(k)); + } + return newKeys; } }