Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start a singleton task in an ada package

Tags:

package

task

ada

I am doing some Ada this Sunday .. ;-)

I have write a small Log package:

log.ads:

package Log is
    procedure log (text: String);
end Log;

log.adb:

with Ada.Text_IO;

package body Log is

    procedure log (text: String) is
    begin
        Ada.Text_IO.Put (text);
    end log;

end Log;

I can use it like this: test.adb:

with Log;

procedure Test is
begin
    Log.log ("bla bla");
end Test;

Now, I would like to "improve" this package. I would like the log procedure to "push" the text to a task. It is the task that does the "Ada.Text_IO.Put (text)". The task can be:

task Logger_Task is
    entry log (text : String);
end Logger_Task;

task body Logger_Task is
begin
    loop
        accept log (text: String) do
            Ada.Text_IO.Put (text);
        end log;
    end loop;
end Logger_Task;

I would like that the Log clients are not aware of this task, so it should be hidden somewhere into the Log package. I do not know how and where to instantiate the task ...

This task must also remain active throughout the duration of the application.

Thanks for your help.

like image 298
ols Avatar asked Dec 18 '22 14:12

ols


2 Answers

You already instantiated it.

task Logger_Task is
    entry log (text : String);
end Logger_Task;

is the same as creating an instance of an anonymous task type:

task type Anonymous is
    entry log (text : String);
end Anonymous;
Logger_Task : Anonymous;
like image 154
egilhh Avatar answered Dec 28 '22 01:12

egilhh


If you define the task in the body of the package, you can keep the procedure log interface:

with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;

package body Log is

   task Logger_Task is
      entry log (text : String);
   end Logger_Task;

   task body Logger_Task is
      Cache: Ada.Strings.Unbounded.Unbounded_String;
   begin
      loop
         select
            accept log (text: String) do
               Cache := Ada.Strings.Unbounded.To_Unbounded_String (text);
            end log;
            Ada.Text_IO.Unbounded_IO.Put (Cache);
         or
            terminate;
         end select;
      end loop;
   end Logger_Task;

   procedure log (text: String) is
   begin
      Logger_Task.log (text);
   end log;
end Log;

select … or terminate; is vital to end the task when the main task ends (this alternative will only be taken when the main task has reached its end).

Cache is also important because it allows the calling task to continue after the text parameter has been received by the accept block. Directly calling Put in the accept block will make the calling task wait for it to finish, since it only continues after the accept block has been left.

like image 41
flyx Avatar answered Dec 28 '22 00:12

flyx