/** * Called to indicate that the last write has been performed. It updates the state and performs * cleanup operations. */ void closed() { while (true) { OutputState state = _state.get(); switch (state) { case CLOSED: { return; } case UNREADY: { if (_state.compareAndSet(state, OutputState.ERROR)) _writeListener.onError( _onError == null ? new EofException("Async closed") : _onError); break; } default: { if (!_state.compareAndSet(state, OutputState.CLOSED)) break; try { _channel.getResponse().closeOutput(); } catch (Throwable x) { if (LOG.isDebugEnabled()) LOG.debug(x); abort(x); } finally { releaseBuffer(); } // Return even if an exception is thrown by closeOutput(). return; } } } }
/* Called to indicated that the output is already closed and the state needs to be updated to match */ void closed() { State state = _state.get(); while (state != State.CLOSED) { if (_state.compareAndSet(state, State.CLOSED)) { try { _channel.getResponse().closeOutput(); } catch (IOException e) { LOG.debug(e); _channel.failed(); } releaseBuffer(); return; } state = _state.get(); } }
@Override public void close() { State state = _state.get(); while (state != State.CLOSED) { if (_state.compareAndSet(state, State.CLOSED)) { try { if (BufferUtil.hasContent(_aggregate)) _channel.write(_aggregate, !_channel.getResponse().isIncluding()); else _channel.write(BufferUtil.EMPTY_BUFFER, !_channel.getResponse().isIncluding()); } catch (IOException e) { LOG.debug(e); _channel.failed(); } releaseBuffer(); return; } state = _state.get(); } }
@Override public void close() { while (true) { OutputState state = _state.get(); switch (state) { case CLOSED: { return; } case ASYNC: case UNREADY: case PENDING: { if (!_state.compareAndSet(state, OutputState.CLOSED)) break; IOException ex = new IOException("Closed while Pending/Unready"); LOG.warn(ex.toString()); LOG.debug(ex); _channel.abort(ex); } default: { if (!_state.compareAndSet(state, OutputState.CLOSED)) break; try { write( BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER, !_channel.getResponse().isIncluding()); } catch (IOException x) { // Ignore it, it's been already logged in write(). } finally { releaseBuffer(); } // Return even if an exception is thrown by write(). return; } } } }