generic
type Element_Type is private;
-- The elements that are pooled
type Factory_Param is private;
with function Factory (Param : Factory_Param) return Element_Type;
-- Information needed to create new elements as needed. This is passed as
-- is to the Factory function.
type Resource_Set is (<>);
-- Represents a set of elements within the pool.
-- There can be multiple such sets in one pool. Each set is associated with
-- its own factory parameter, but all other elements are compatible between
-- the various sets (in particular, the resources are the same, so the rest
-- of the application doesn't need to know which set this resource is
-- from).
-- Most times, a pool will need only one such subset, which is created by
-- default. All subprograms below apply to this default set, unless
-- otherwise specified.
with procedure Free (Self : in out Element_Type) is null;
-- Called when the [Self] is finally removed from the pool
with procedure On_Release (Self : in out Element_Type) is null;
-- Called when Self is released into the pool.
-- The application has no more reference to that element, apart from the
-- one in the pool.
-- The result of Element.Element should not be freed yet, since it is
-- returned to the pool (instead, override the formal [Free] parameter).
-- But any other custom field from Element should be reset at that time.
with procedure Free_Param (Data : in out Factory_Param) is null;
-- Free Factory_Param.
-- Called when the pool itself is freed.
package GNATCOLL.Pools is
Default_Set : constant Resource_Set;
type Resource is tagged private;
No_Resource : constant Resource;
-- A resource retrieved from the pool.
-- This is a smart pointer to an Element_Type. When your application has no
-- more references to it, the Element_Type is released into the pool (not
-- destroyed).
-- The resource itself does its refcounting in a task-safe manner.
function Element (Self : Resource) return access Element_Type;
-- Get a copy of the element stored in the wrapper. The result should
-- really only be used while you have a handle on Self, so that you are
-- sure it has not been released into the pool, and thus reset.
type Weak_Resource is private;
Null_Weak_Resource : constant Weak_Resource;
function Get_Weak (Self : Resource'Class) return Weak_Resource;
procedure Get (Self : Weak_Resource; Res : out Resource);
-- A resource with a weak-reference.
-- Such a resource does not prevent the release into the pool when no other
-- Resource exists. While the resource has not been released, you can get
-- access to it through this Weak_Resource. One it has been released, the
-- Weak_Resource will return No_Resource.
-- This datatype can thus be stored in some long-lived data structure, if
-- you do not want to prevent the release. For instance if you have a
-- cache of some sort.
function Was_Freed (Self : Weak_Resource) return Boolean;
-- Whether the resource monitored by Self was released.
procedure Set_Factory
(Param : Factory_Param;
Max_Elements : Positive;
Set : Resource_Set := Default_Set);
-- Configure the internal resource pool. This must be called before
-- calling Get, and only once.
procedure Get
(Self : out Resource'Class;
Set : Resource_Set := Default_Set);
-- Return an available resource (or create a new one if the pool is not
-- full yet and none is available).
-- In a multitasking context, this blocks until a resource is actually
-- available.
-- The resource is automatically released when you no longer have a
-- reference to the wrapper.
procedure Free;
-- Detach all resources from the pool.
-- Any resource that is not in use elsewhere (i.e. retrieved by Get) will
-- get freed (and the corresponding [Free] formal subprogram will be
-- called).
function Get_Refcount (Self : Resource) return Natural;
-- Return the reference counting for self
function Get_Factory_Param
(Set : Resource_Set := Default_Set) return access Factory_Param;
-- Returns the Factory_Param used for the set.
-- Remember that the factory will not be called again for resources that
-- have already been created, even if they have been released to the pool
-- since then.
-- This must only be called when you have called Set_Factory for the
-- corresponding set.
-- The returned value is shared among multiple threads, so you should only
-- modify it from a protected region or before tasks are created.
end GNATCOLL.Pools;