with Rx.Dispatchers.Single; private with Ada.Containers; private with Ada.Containers.Vectors; private with Ada.Finalization; package Rx.Dispatchers.Pools is type String_Access is access all String; type Pool (Initial_Size : Positive := 8; Name : String_Access := new String'("anonymous")) is tagged limited private; function Get (From : in out Pool; Reuse : Boolean := False) return Single.Ptr; -- In round-robin fashion -- If Reuse and last returned thread is idle, return it again function Curr_Or_Next (From : in out Pool) return Single.Ptr is (From.Get (Reuse => True)); -- Return current in pool if idle, or next one regardless of idleness function Find_Idle (From : in out Pool; Grow : Boolean := True) return Single.Ptr; -- Returns next idle thread, or create one if Grow and none idle (can go beyond initial size) -- Returns next non-idle if none idle and not grow -- NOTE: THIS IS O(N) in the current implementation function New_One (From : in out Pool) return Single.Ptr; -- Grows the pool and returns the new one private use type Single.Ptr; package Thread_Vectors is new Ada.Containers.Vectors (Positive, Single.Ptr); protected type Safe_Pool (Parent : access Pool) is procedure Advance; procedure Append (Thread : Single.Ptr); -- Append a new single y return the current number in the pool -- There's potential for race conditions here in which we could end with some extra threads -- But it may serve as a simpler implementation procedure Curr (Thread : out Single.Ptr); procedure Find_Idle (Thread : out Single.Ptr); function Exists return Boolean; -- Say if the Current thread exists function Thread_Count return Natural; private Threads : Thread_Vectors.Vector; Current : Positive := 1; Size : Positive := Parent.Initial_Size; -- Max of the actual size or initial size -- There might be less than Size created elements in Threads end Safe_Pool; type Pool (Initial_Size : Positive := 8; Name : String_Access := new String'("anonymous")) is new Ada.Finalization.Limited_Controlled with record Safe : Safe_Pool (Pool'Access); end record; function Grow (This : in out Pool) return Single.Ptr; -- Adds a thread and returns it, going beyond initial capacity if necessary function Ensure_Exists (This : in out Pool) return Single.Ptr; -- Returns null if already exists, or else the newly created thread overriding procedure Finalize (This : in out Pool); end Rx.Dispatchers.Pools;