Interface Retainable

All Known Subinterfaces:
Content.Chunk, RetainableByteBuffer, RetainableByteBuffer.Mutable
All Known Implementing Classes:
AbstractRetainableByteBuffer, ArrayByteBufferPool.Tracking.TrackedBuffer, Content.Chunk.Empty, Retainable.ReferenceCounter, Retainable.Wrapper, RetainableByteBuffer.Abstract, RetainableByteBuffer.DynamicCapacity, RetainableByteBuffer.EmptyRetainableByteBuffer, RetainableByteBuffer.FixedCapacity, RetainableByteBuffer.NonRetainableByteBuffer, RetainableByteBuffer.Pooled, RetainableByteBuffer.Wrapper

public interface Retainable

A reference counted resource, for example one that is borrowed from a pool, that may be retained an additional number of times, and released a correspondent number of times, over its lifecycle.

The resource is typically implicitly retained when it is first created. It may be retained more times (thus incrementing its reference count) and released (thus decrementing its reference count), until the reference count goes to zero.

Idiomatic usage

The general rules to use Retainable objects are the following:

  1. If the Retainable has been obtained by calling a method, and the caller code consumes it, then the caller code must call release().
  2. If the Retainable has been obtained by caller2 by calling a method, and caller2 returns it without consuming it to caller1, then caller2 must not call release(), since caller1 will.
  3. If the Retainable has been obtained as a method argument, the receiver code must either:
    1. Consume the Retainable synchronously within the method, in which case release() must not be called.
    2. Pass the Retainable to some other method, in which case release() must not be called.
    3. Store away the Retainable for later or asynchronous processing, for example storing it in containers such as Collections, or capturing it in a lambda that is passed to another thread, etc., in which case retain() must be called and a mechanism to call release() later or asynchronously for this additional retain() must be arranged.