code: @Override
  	public NotificationResult notifyBufferAvailable(Buffer buffer) {
  		NotificationResult notificationResult = NotificationResult.BUFFER_NOT_USED;
  		try {
  			synchronized (bufferQueue) {
  				checkState(isWaitingForFloatingBuffers,
  					"This channel should be waiting for floating buffers.");
  
  				// Important: make sure that we never add a buffer after releaseAllResources()
  				// released all buffers. Following scenarios exist:
  				// 1) releaseAllResources() already released buffers inside bufferQueue
  				// -> then isReleased is set correctly
  				// 2) releaseAllResources() did not yet release buffers from bufferQueue
  				// -> we may or may not have set isReleased yet but will always wait for the
  				// lock on bufferQueue to release buffers
  				if (isReleased.get() || bufferQueue.getAvailableBufferSize() >= numRequiredBuffers) {
  					isWaitingForFloatingBuffers = false;
  					return notificationResult;
  				}
  
  				bufferQueue.addFloatingBuffer(buffer);
  
  				if (bufferQueue.getAvailableBufferSize() == numRequiredBuffers) {
  					isWaitingForFloatingBuffers = false;
  					notificationResult = NotificationResult.BUFFER_USED_NO_NEED_MORE;
  				} else {
  					notificationResult = NotificationResult.BUFFER_USED_NEED_MORE;
  				}
  			}
  
  			if (unannouncedCredit.getAndAdd(1) == 0) {
  				notifyCreditAvailable();
  			}
  		} catch (Throwable t) {
  			setError(t);
  		}
  		return notificationResult;
  	}
docs: The Buffer pool notifies this channel of an available floating buffer. If the channel is released or
  currently does not need extra buffers, the buffer should be returned to the buffer pool. Otherwise,
  the buffer will be added into the <tt>bufferQueue</tt> and the unannounced credit is increased
  by one.
  
  @param buffer Buffer that becomes available in buffer pool.
  @return NotificationResult indicates whether this channel accepts the buffer and is waiting for
  more floating buffers.