VirtualChannelSelectorpublic class VirtualChannelSelector extends Object
Fields Summary |
---|
private static final LogIDs | LOGID | public static final int | OP_ACCEPT | public static final int | OP_CONNECT | public static final int | OP_READ | public static final int | OP_WRITE | private boolean | SAFE_SELECTOR_MODE_ENABLED | private static final boolean | TEST_SAFE_MODE | private static final int | MAX_CHANNELS_PER_SAFE_SELECTOR | private static final int | MAX_SAFEMODE_SELECTORS | private String | name | private com.aelitis.azureus.core.networkmanager.impl.tcp.VirtualChannelSelectorImpl | selector_impl | private volatile boolean | destroyed | private HashMap | selectors | private HashSet | selectors_keyset_cow | private org.gudy.azureus2.core3.util.AEMonitor | selectors_mon | private final int | op | private final boolean | pause |
Constructors Summary |
---|
public VirtualChannelSelector(String name, int interest_op, boolean pause_after_select)Create a new virtual selectable-channel selector, selecting over the given interest-op.
this.name = name;
this.op = interest_op;
this.pause = pause_after_select;
if( SAFE_SELECTOR_MODE_ENABLED ) {
initSafeMode();
}
else {
selector_impl = new VirtualChannelSelectorImpl( this, op, pause );
selectors = null;
selectors_keyset_cow = null;
selectors_mon = null;
}
|
Methods Summary |
---|
public void | cancel(java.nio.channels.spi.AbstractSelectableChannel channel)Cancel the selection operations for the given channel.
if( SAFE_SELECTOR_MODE_ENABLED ) {
try{ selectors_mon.enter();
//System.out.println( "cancel - " + channel.hashCode() + " - " + Debug.getCompressedStackTrace());
for( Iterator it = selectors.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
VirtualChannelSelectorImpl sel = (VirtualChannelSelectorImpl)entry.getKey();
ArrayList channels = (ArrayList)entry.getValue();
if( channels.remove( channel ) ) {
sel.cancel( channel );
return;
}
}
}
finally{ selectors_mon.exit(); }
}
else {
if( selector_impl != null ) selector_impl.cancel( channel );
}
| public void | destroy()
destroyed = true;
if ( SAFE_SELECTOR_MODE_ENABLED ){
for( Iterator it = selectors_keyset_cow.iterator(); it.hasNext(); ) {
VirtualChannelSelectorImpl sel = (VirtualChannelSelectorImpl)it.next();
sel.destroy();
}
}else{
selector_impl.destroy();
}
| public void | enableSafeSelectionMode()
if( !SAFE_SELECTOR_MODE_ENABLED ) {
SAFE_SELECTOR_MODE_ENABLED = true;
COConfigurationManager.setParameter( "network.tcp.enable_safe_selector_mode", true );
initSafeMode();
}
| public java.lang.String | getName()
return( name );
| private void | initSafeMode()
//System.out.println( "***************** SAFE SOCKET SELECTOR MODE ENABLED *****************" );
if (Logger.isEnabled()) {
Logger.log(new LogEvent(LOGID, "***************** SAFE SOCKET SELECTOR MODE ENABLED *****************"));
}
selector_impl = null;
selectors = new HashMap();
selectors_mon = new AEMonitor( "VirtualChannelSelector:FM" );
selectors.put( new VirtualChannelSelectorImpl( this, op, pause ), new ArrayList() );
selectors_keyset_cow = new HashSet( selectors.keySet());
| public boolean | isDestroyed()
return( destroyed );
| public boolean | isSafeSelectionModeEnabled() return SAFE_SELECTOR_MODE_ENABLED;
| public void | pauseSelects(java.nio.channels.spi.AbstractSelectableChannel channel)Pause selection operations for the given channel
if( SAFE_SELECTOR_MODE_ENABLED ) {
try{ selectors_mon.enter();
//System.out.println( "pause - " + channel.hashCode() + " - " + Debug.getCompressedStackTrace());
for( Iterator it = selectors.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
VirtualChannelSelectorImpl sel = (VirtualChannelSelectorImpl)entry.getKey();
ArrayList channels = (ArrayList)entry.getValue();
if( channels.contains( channel ) ) {
sel.pauseSelects( channel );
return;
}
}
Debug.out( "pauseSelects():: channel not found!" );
}
finally{ selectors_mon.exit(); }
}
else {
selector_impl.pauseSelects( channel );
}
| public void | register(java.nio.channels.SocketChannel channel, com.aelitis.azureus.core.networkmanager.VirtualChannelSelector$VirtualSelectorListener listener, java.lang.Object attachment)
registerSupport( channel, listener, attachment );
| public void | register(java.nio.channels.ServerSocketChannel channel, com.aelitis.azureus.core.networkmanager.VirtualChannelSelector$VirtualAcceptSelectorListener listener, java.lang.Object attachment)
registerSupport( channel, listener, attachment );
| protected void | registerSupport(java.nio.channels.spi.AbstractSelectableChannel channel, com.aelitis.azureus.core.networkmanager.VirtualChannelSelector$VirtualAbstractSelectorListener listener, java.lang.Object attachment)Register the given selectable channel, using the given listener for notification
of completed select operations.
NOTE: For OP_CONNECT and OP_WRITE -type selectors, once a selection request op
completes, the channel's op registration is automatically disabled (paused); any
future wanted selection notification requires re-enabling via resume. For OP_READ selectors,
it stays enabled until actively paused, no matter how many times it is selected.
if( SAFE_SELECTOR_MODE_ENABLED ) {
try{ selectors_mon.enter();
//System.out.println( "register - " + channel.hashCode() + " - " + Debug.getCompressedStackTrace());
for( Iterator it = selectors.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
VirtualChannelSelectorImpl sel = (VirtualChannelSelectorImpl)entry.getKey();
ArrayList channels = (ArrayList)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 chan_it = channels.iterator();
while( chan_it.hasNext()){
AbstractSelectableChannel chan = (AbstractSelectableChannel)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 );
ArrayList chans = new ArrayList();
selectors.put( sel, chans );
sel.register( channel, listener, attachment );
chans.add( channel );
selectors_keyset_cow = new HashSet( selectors.keySet());
}
finally{ selectors_mon.exit(); }
}
else {
selector_impl.register( channel, listener, attachment );
}
| public void | resumeSelects(java.nio.channels.spi.AbstractSelectableChannel channel)Resume selection operations for the given channel
if( SAFE_SELECTOR_MODE_ENABLED ) {
try{ selectors_mon.enter();
//System.out.println( "resume - " + channel.hashCode() + " - " + Debug.getCompressedStackTrace());
for( Iterator it = selectors.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
VirtualChannelSelectorImpl sel = (VirtualChannelSelectorImpl)entry.getKey();
ArrayList channels = (ArrayList)entry.getValue();
if( channels.contains( channel ) ) {
sel.resumeSelects( channel );
return;
}
}
Debug.out( "resumeSelects():: channel not found!" );
}
finally{ selectors_mon.exit(); }
}
else {
selector_impl.resumeSelects( channel );
}
| public int | select(long timeout)Run a virtual select() operation, with the given selection timeout value;
(1) cancellations are processed (2) the select operation is performed; (3)
listener notification of completed selects (4) new registrations are processed
if( SAFE_SELECTOR_MODE_ENABLED ) {
boolean was_destroyed = destroyed;
try{
int count = 0;
for( Iterator it = selectors_keyset_cow.iterator(); it.hasNext(); ){
VirtualChannelSelectorImpl sel = (VirtualChannelSelectorImpl)it.next();
count += sel.select( timeout );
}
return count;
}finally{
if ( was_destroyed ){
// destruction process requires select op after destroy...
try{
selectors_mon.enter();
selectors.clear();
selectors_keyset_cow = new HashSet();
}finally{
selectors_mon.exit();
}
}
}
}
return selector_impl.select( timeout );
| public void | selectFailure(com.aelitis.azureus.core.networkmanager.VirtualChannelSelector$VirtualAbstractSelectorListener listener, java.nio.channels.spi.AbstractSelectableChannel sc, java.lang.Object attachment, java.lang.Throwable msg)
if ( op == OP_ACCEPT ){
((VirtualAcceptSelectorListener)listener).selectFailure( VirtualChannelSelector.this, (ServerSocketChannel)sc, attachment, msg );
}else{
((VirtualSelectorListener)listener).selectFailure( VirtualChannelSelector.this, (SocketChannel)sc, attachment, msg );
}
| public boolean | selectSuccess(com.aelitis.azureus.core.networkmanager.VirtualChannelSelector$VirtualAbstractSelectorListener listener, java.nio.channels.spi.AbstractSelectableChannel sc, java.lang.Object attachment)
if ( op == OP_ACCEPT ){
return(((VirtualAcceptSelectorListener)listener).selectSuccess( VirtualChannelSelector.this, (ServerSocketChannel)sc, attachment ));
}else{
return(((VirtualSelectorListener)listener).selectSuccess( VirtualChannelSelector.this, (SocketChannel)sc, attachment ));
}
|
|