4.2.40. GNATCOLL.Pools

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;