code: final protected void handleProcessedBuffer(T buffer, IOException ex) {
  		if (buffer == null) {
  			return;
  		}
  
  		// even if the callbacks throw an error, we need to maintain our bookkeeping
  		try {
  			if (ex != null && this.exception == null) {
  				this.exception = ex;
  				this.resultHandler.requestFailed(buffer, ex);
  			}
  			else {
  				this.resultHandler.requestSuccessful(buffer);
  			}
  		}
  		finally {
  			NotificationListener listener = null;
  
  			// Decrement the number of outstanding requests. If we are currently closing, notify the
  			// waiters. If there is a listener, notify her as well.
  			synchronized (this.closeLock) {
  				if (this.requestsNotReturned.decrementAndGet() == 0) {
  					if (this.closed) {
  						this.closeLock.notifyAll();
  					}
  
  					synchronized (listenerLock) {
  						listener = allRequestsProcessedListener;
  						allRequestsProcessedListener = null;
  					}
  				}
  			}
  
  			if (listener != null) {
  				listener.onNotification();
  			}
  		}
  	}
docs: Handles a processed <tt>Buffer</tt>. This method is invoked by the
  asynchronous IO worker threads upon completion of the IO request with the
  provided buffer and/or an exception that occurred while processing the request
  for that buffer.
  
  @param buffer The buffer to be processed.
  @param ex     The exception that occurred in the I/O threads when processing the buffer's request.