Reputation: 8267
Is there a pattern for a fire and forget mechanism in Ada? When I call a task entry, I don't want the caller to be blocked until the message has been processed. I would like the task to be asynchronous. What I've tried is
loop
select
accept xxx(params) do
-- save the parameters in a queue
end accept;
...
else
-- pick the next item off the queue and process it
end select;
end loop;
It looks like a clumsy mechanism. Maybe fire and forget is the wrong term. I've also tried one task filling up the queue and another taking entries off the queue. Is there a better way of implementing asynchronous tasks in Ada.
Upvotes: 3
Views: 399
Reputation: 25511
If you’re using Ada 2012, the way to go would be to use Ada.Containers.Unbounded_Synchronized_Queues (or the Bounded version): your user code calls Enqueue
, your server task calls Dequeue
which blocks if the queue is empty.
If not, the normal approach would be to use your own protected object to encapsulate a queue (which is how the Ada 2012 packages do it). Something like
package Parameters is new Ada.Containers.Vectors (Positive, Parameter);
protected Queue is
procedure Put (P : Parameter);
entry Get (P : out Parameter);
private
The_Queue : Parameters.Vector;
end Queue;
protected body Queue is
procedure Put (P : Parameter) is
begin
The_Queue.Append (P);
end Put;
entry Get (P : out Parameter) when not The_Queue.Is_Empty is
begin
P := The_Queue.First_Element;
The_Queue.Delete_First;
end Get;
end Queue;
and then
task body Server is
P : Parameter;
begin
loop
Queue.Get (P);
-- process P
end loop;
end Server;
Upvotes: 4