public void exchangeComplete(final HttpServerExchange exchange) {
connection.clearChannel();
final HttpServerConnection connection = this.connection;
if (exchange.isPersistent() && !exchange.isUpgrade()) {
final StreamConnection channel = connection.getChannel();
if (connection.getExtraBytes() == null) {
//if we are not pipelining we just register a listener
//we have to resume from with the io thread
if (exchange.isInIoThread()) {
//no need for CAS, we are in the IO thread
newRequest();
channel.getSourceChannel().setReadListener(HttpReadListener.this);
channel.getSourceChannel().resumeReads();
requestStateUpdater.set(this, 0);
} else {
while (true) {
if (connection.getOriginalSourceConduit().isReadShutdown() || connection.getOriginalSinkConduit().isWriteShutdown()) {
channel.getSourceChannel().suspendReads();
channel.getSinkChannel().suspendWrites();
IoUtils.safeClose(connection);
return;
} else {
if (requestStateUpdater.compareAndSet(this, 1, 2)) {
newRequest();
channel.getSourceChannel().setReadListener(HttpReadListener.this);
requestStateUpdater.set(this, 0);
channel.getSourceChannel().resumeReads();
break;
}
}
}
}
} else {
if (exchange.isInIoThread()) {
requestStateUpdater.set(this, 0); //no need to CAS, as we don't actually resume
newRequest();
//no need to suspend reads here, the task will always run before the read listener anyway
channel.getIoThread().execute(this);
} else {
while (true) {
if (connection.getOriginalSinkConduit().isWriteShutdown()) {
channel.getSourceChannel().suspendReads();
channel.getSinkChannel().suspendWrites();
IoUtils.safeClose(connection);
return;
} else if (requestStateUpdater.compareAndSet(this, 1, 2)) {
newRequest();
channel.getSourceChannel().suspendReads();
requestStateUpdater.set(this, 0);
break;
}
}
Executor executor = exchange.getDispatchExecutor();