if( SAFE_SELECTOR_MODE_ENABLED ) {
try{ selectors_mon.enter();
//System.out.println( "register - " + channel.hashCode() + " - " + Debug.getCompressedStackTrace());
for( Map.Entry<VirtualChannelSelectorImpl, ArrayList<AbstractSelectableChannel>> entry: selectors.entrySet()) {
VirtualChannelSelectorImpl sel = entry.getKey();
ArrayList<AbstractSelectableChannel> channels = entry.getValue();
if( channels.size() >= ( TEST_SAFE_MODE?0:MAX_CHANNELS_PER_SAFE_SELECTOR )) {
// it seems that we have a bug somewhere where a selector is being registered
// but not cancelled on close. As an interim fix scan channels and remove any
// closed ones
Iterator<AbstractSelectableChannel> chan_it = channels.iterator();
while( chan_it.hasNext()){
AbstractSelectableChannel chan = chan_it.next();
if ( !chan.isOpen()){
Debug.out( "Selector '" + getName() + "' - removing orphaned safe channel registration" );
chan_it.remove();
}
}
}
if( channels.size() < MAX_CHANNELS_PER_SAFE_SELECTOR ) { //there's room in the current selector
sel.register( channel, listener, attachment );
channels.add( channel );
return;
}
}
//we couldnt find room in any of the existing selectors, so start up a new one if allowed
//max limit to the number of Selectors we are allowed to create
if( selectors.size() >= MAX_SAFEMODE_SELECTORS ) {
String msg = "Error: MAX_SAFEMODE_SELECTORS reached [" +selectors.size()+ "], no more socket channels can be registered. Too many peer connections.";
Debug.out( msg );
selectFailure( listener, channel, attachment, new Throwable( msg ) ); //reject registration
return;
}
if ( destroyed ){
String msg = "socket registered after controller destroyed";
Debug.out( msg );
selectFailure( listener, channel, attachment, new Throwable( msg ) ); //reject registration
return;
}
VirtualChannelSelectorImpl sel = new VirtualChannelSelectorImpl( this, op, pause , randomise_keys);
ArrayList<AbstractSelectableChannel> chans = new ArrayList<AbstractSelectableChannel>();
selectors.put( sel, chans );
sel.register( channel, listener, attachment );
chans.add( channel );
selectors_keyset_cow = new HashSet<VirtualChannelSelectorImpl>( selectors.keySet());
}