docs: @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;
  	}