* Super-classes can implement this method to react to the event. * * @param key the selection key. */ protected abstract void acceptable(SelectionKey key); /** * Triggered when the key signals {@link SelectionKey#OP_CONNECT} readiness. *
* Super-classes can implement this method to react to the event. * * @param key the selection key. */ protected abstract void connectable(SelectionKey key); /** * Triggered when the key signals {@link SelectionKey#OP_READ} readiness. *
* Super-classes can implement this method to react to the event. * * @param key the selection key. */ protected abstract void readable(SelectionKey key); /** * Triggered when the key signals {@link SelectionKey#OP_WRITE} readiness. *
* Super-classes can implement this method to react to the event. * * @param key the selection key. */ protected abstract void writable(SelectionKey key); /** * Triggered to validate keys currently registered with the selector. This * method is called after each I/O select loop. *
* Super-classes can implement this method to run validity checks on
* active sessions and include additional processing that needs to be
* executed after each I/O select loop.
*
* @param keys all selection keys registered with the selector.
*/
protected abstract void validate(Set
* Super-classes can implement this method to react to the event.
*
* @param key the selection key.
* @param session new I/O session.
*/
protected void sessionCreated(final SelectionKey key, final IOSession session) {
}
/**
* Triggered when a session has been closed.
*
* Super-classes can implement this method to react to the event.
*
* @param session closed I/O session.
*/
protected void sessionClosed(final IOSession session) {
}
/**
* Triggered when a session has timed out.
*
* Super-classes can implement this method to react to the event.
*
* @param session timed out I/O session.
*/
protected void sessionTimedOut(final IOSession session) {
}
/**
* Obtains {@link IOSession} instance associated with the given selection
* key.
*
* @param key the selection key.
* @return I/O session.
*/
protected IOSession getSession(final SelectionKey key) {
return (IOSession) key.attachment();
}
public IOReactorStatus getStatus() {
return this.status;
}
/**
* Returns
* This method will enter the infinite I/O select loop on
* the {@link Selector} instance associated with this I/O reactor.
*
* The method will remain blocked unto the I/O reactor is shut down or the
* execution thread is interrupted.
*
* @see #acceptable(SelectionKey)
* @see #connectable(SelectionKey)
* @see #readable(SelectionKey)
* @see #writable(SelectionKey)
* @see #timeoutCheck(SelectionKey, long)
* @see #validate(Set)
* @see #sessionCreated(SelectionKey, IOSession)
* @see #sessionClosed(IOSession)
*
* @throws InterruptedIOException if the dispatch thread is interrupted.
* @throws IOReactorException in case if a non-recoverable I/O error.
*/
protected void execute() throws InterruptedIOException, IOReactorException {
this.status = IOReactorStatus.ACTIVE;
try {
for (;;) {
int readyCount;
try {
readyCount = this.selector.select(this.selectTimeout);
} catch (InterruptedIOException ex) {
throw ex;
} catch (IOException ex) {
throw new IOReactorException("Unexpected selector failure", ex);
}
if (this.status == IOReactorStatus.SHUT_DOWN) {
// Hard shut down. Exit select loop immediately
break;
}
if (this.status == IOReactorStatus.SHUTTING_DOWN) {
// Graceful shutdown in process
// Try to close things out nicely
closeSessions();
closeNewChannels();
}
// Process selected I/O events
if (readyCount > 0) {
processEvents(this.selector.selectedKeys());
}
// Validate active channels
validate(this.selector.keys());
// Process closed sessions
processClosedSessions();
// If active process new channels
if (this.status == IOReactorStatus.ACTIVE) {
processNewChannels();
}
// Exit select loop if graceful shutdown has been completed
if (this.status.compareTo(IOReactorStatus.ACTIVE) > 0
&& this.sessions.isEmpty()) {
break;
}
if (this.interestOpsQueueing) {
// process all pending interestOps() operations
processPendingInterestOps();
}
}
} catch (ClosedSelectorException ex) {
} finally {
hardShutdown();
synchronized (this.statusMutex) {
this.statusMutex.notifyAll();
}
}
}
private void processEvents(final Set
* Super-classes can implement this method to react to the event.
*
* @param key the selection key.
* @param now current time as long value.
*/
protected void timeoutCheck(final SelectionKey key, long now) {
IOSessionImpl session = (IOSessionImpl) key.attachment();
if (session != null) {
int timeout = session.getSocketTimeout();
if (timeout > 0) {
if (session.getLastAccessTime() + timeout < now) {
sessionTimedOut(session);
}
}
}
}
/**
* Closes out all I/O sessions maintained by this I/O reactor.
*/
protected void closeSessions() {
synchronized (this.sessions) {
for (Iteratortrue
if interest Ops queueing is enabled, false
otherwise.
*
* @since 4.1
*/
public boolean getInterestOpsQueueing() {
return this.interestOpsQueueing;
}
/**
* Adds new channel entry. The channel will be asynchronously registered
* with the selector.
*
* @param channelEntry the channel entry.
*/
public void addChannel(final ChannelEntry channelEntry) {
if (channelEntry == null) {
throw new IllegalArgumentException("Channel entry may not be null");
}
this.newChannels.add(channelEntry);
this.selector.wakeup();
}
/**
* Activates the I/O reactor. The I/O reactor will start reacting to
* I/O events and triggering notification methods.
*