Closing Channels in Ada

with Ada.Text_IO;

procedure Closing_Channels is
   package IO renames Ada.Text_IO;

   type Job_Type is new Integer;
   
   task type Worker is
      entry Start;
      entry Job(J : Job_Type);
      entry Stop;
   end Worker;

   task body Worker is
   begin
      accept Start;
      loop
         select
            accept Job(J : Job_Type) do
               IO.Put_Line("received job" & J'Image);
            end Job;
         or
            accept Stop;
            IO.Put_Line("received all jobs");
            exit;
         end select;
      end loop;
   end Worker;

   W : Worker;
begin
   W.Start;

   for J in 1..3 loop
      W.Job(Job_Type(J));
      IO.Put_Line("sent job" & J'Image);
   end loop;

   IO.Put_Line("sent all jobs");
   W.Stop;
end Closing_Channels;

In this Ada example, we demonstrate a concept similar to closing channels. Ada doesn’t have built-in channels, so we use tasks and rendezvous for communication between concurrent units.

The Worker task type represents our worker. It has three entries:

  • Start: to initiate the worker.
  • Job: to receive a job.
  • Stop: to signal that no more jobs will be sent.

In the main procedure:

  1. We create a worker task W.

  2. We start the worker by calling W.Start.

  3. We send three jobs to the worker using a loop:

    for J in 1..3 loop
       W.Job(Job_Type(J));
       IO.Put_Line("sent job" & J'Image);
    end loop;
  4. After sending all jobs, we call W.Stop to signal that no more jobs will be sent. This is analogous to closing a channel in the original example.

  5. The worker task will process jobs until it receives the Stop signal, at which point it will print “received all jobs” and terminate.

This Ada code demonstrates concurrent communication and termination signaling, which are the key concepts from the original example. The select statement in the worker task allows it to handle both job reception and termination signaling.

To run this program, save it as closing_channels.adb and compile it with an Ada compiler:

$ gnatmake closing_channels.adb
$ ./closing_channels
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs

This example showcases Ada’s tasking model, which provides a different but powerful approach to concurrency compared to channel-based models.