FileDocCategorySizeDatePackage
AbstractSelectableChannel.javaAPI DocJava SE 5 API7997Fri Aug 26 14:57:10 BST 2005java.nio.channels.spi

AbstractSelectableChannel

public abstract class AbstractSelectableChannel extends SelectableChannel
Base implementation class for selectable channels.

This class defines methods that handle the mechanics of channel registration, deregistration, and closing. It maintains the current blocking mode of this channel as well as its current set of selection keys. It performs all of the synchronization required to implement the {@link java.nio.channels.SelectableChannel} specification. Implementations of the abstract protected methods defined in this class need not synchronize against other threads that might be engaged in the same operations.

author
Mark Reinhold
author
Mike McCloskey
author
JSR-51 Expert Group
version
1.25, 03/12/19
since
1.4

Fields Summary
private final SelectorProvider
provider
private SelectionKey[]
keys
private int
keyCount
private final Object
keyLock
private final Object
regLock
boolean
blocking
Constructors Summary
protected AbstractSelectableChannel(SelectorProvider provider)
Initializes a new instance of this class.


                
       
	this.provider = provider;
    
Methods Summary
private voidaddKey(java.nio.channels.SelectionKey k)

	synchronized (keyLock) {
	    int i = 0;
	    if ((keys != null) && (keyCount < keys.length)) {
		// Find empty element of key array
		for (i = 0; i < keys.length; i++)
		    if (keys[i] == null)
			break;
	    } else if (keys == null) {
                keys =  new SelectionKey[3];
            } else {
		// Grow key array
		int n = keys.length * 2;
		SelectionKey[] ks =  new SelectionKey[n];
		for (i = 0; i < keys.length; i++)
		    ks[i] = keys[i];
		keys = ks;
		i = keyCount;
	    }
	    keys[i] = k;
	    keyCount++;
	}
    
public final java.lang.ObjectblockingLock()

	return regLock;
    
public final java.nio.channels.SelectableChannelconfigureBlocking(boolean block)
Adjusts this channel's blocking mode.

If the given blocking mode is different from the current blocking mode then this method invokes the {@link #implConfigureBlocking implConfigureBlocking} method, while holding the appropriate locks, in order to change the mode.

        if (!isOpen())
            throw new ClosedChannelException();
	synchronized (regLock) {
	    if (blocking == block)
		return this;
	    if (block && haveValidKeys())
		throw new IllegalBlockingModeException();
	    implConfigureBlocking(block);
	    blocking = block;
	}
	return this;
    
private java.nio.channels.SelectionKeyfindKey(java.nio.channels.Selector sel)

	synchronized (keyLock) {
            if (keys == null)
                return null;
	    for (int i = 0; i < keys.length; i++)
                if ((keys[i] != null) && (keys[i].selector() == sel))
                    return keys[i];
	    return null;
	}
    
private booleanhaveValidKeys()

	synchronized (keyLock) {
	    if (keyCount == 0)
		return false;
	    for (int i = 0; i < keys.length; i++) {
		if ((keys[i] != null) && keys[i].isValid())
		    return true;
	    }
	    return false;
	}
    
protected final voidimplCloseChannel()
Closes this channel.

This method, which is specified in the {@link AbstractInterruptibleChannel} class and is invoked by the {@link java.nio.channels.Channel#close close} method, in turn invokes the {@link #implCloseSelectableChannel implCloseSelectableChannel} method in order to perform the actual work of closing this channel. It then cancels all of this channel's keys.

	implCloseSelectableChannel();
	synchronized (keyLock) {
            int count = (keys == null) ? 0 : keys.length;
	    for (int i = 0; i < count; i++) {
		SelectionKey k = keys[i];
		if (k != null)
		    k.cancel();
	    }
	}
    
protected abstract voidimplCloseSelectableChannel()
Closes this selectable channel.

This method is invoked by the {@link java.nio.channels.Channel#close close} method in order to perform the actual work of closing the channel. This method is only invoked if the channel has not yet been closed, and it is never invoked more than once.

An implementation of this method must arrange for any other thread that is blocked in an I/O operation upon this channel to return immediately, either by throwing an exception or by returning normally.

protected abstract voidimplConfigureBlocking(boolean block)
Adjusts this channel's blocking mode.

This method is invoked by the {@link #configureBlocking configureBlocking} method in order to perform the actual work of changing the blocking mode. This method is only invoked if the new mode is different from the current mode.

throws
IOException If an I/O error occurs

public final booleanisBlocking()

	synchronized (regLock) {
	    return blocking;
	}
    
public final booleanisRegistered()

	synchronized (keyLock) {
	    return keyCount != 0;
	}
    
public final java.nio.channels.SelectionKeykeyFor(java.nio.channels.Selector sel)

	return findKey(sel);
    
public final java.nio.channels.spi.SelectorProviderprovider()
Returns the provider that created this channel.

return
The provider that created this channel

	return provider;
    
public final java.nio.channels.SelectionKeyregister(java.nio.channels.Selector sel, int ops, java.lang.Object att)
Registers this channel with the given selector, returning a selection key.

This method first verifies that this channel is open and that the given initial interest set is valid.

If this channel is already registered with the given selector then the selection key representing that registration is returned after setting its interest set to the given value.

Otherwise this channel has not yet been registered with the given selector, so the {@link AbstractSelector#register register} method of the selector is invoked while holding the appropriate locks. The resulting key is added to this channel's key set before being returned.

	if (!isOpen())
	    throw new ClosedChannelException();
	if ((ops & ~validOps()) != 0)
	    throw new IllegalArgumentException();
	synchronized (regLock) {
	    if (blocking)
		throw new IllegalBlockingModeException();
	    SelectionKey k = findKey(sel);
            if (k != null) {
                k.interestOps(ops);
		k.attach(att);
            }
	    if (k == null) {
		// New registration
		k = ((AbstractSelector)sel).register(this, ops, att);
		addKey(k);
	    }
            return k;
        }
    
voidremoveKey(java.nio.channels.SelectionKey k)

			// package-private
	synchronized (keyLock) {
	    for (int i = 0; i < keys.length; i++)
		if (keys[i] == k) {
		    keys[i] = null;
		    keyCount--;
		}
	    ((AbstractSelectionKey)k).invalidate();
	}