comp.lang.ada
 help / color / mirror / Atom feed
From: Brad Moore <brad.moore@shaw.ca>
Subject: Re: Termination of tasks waiting on a protected queue
Date: Sun, 18 May 2014 17:05:59 -0600
Date: 2014-05-18T17:05:59-06:00	[thread overview]
Message-ID: <r1bev.2487052$g45.860535@fx10.iad> (raw)
In-Reply-To: <slrnlngofv.i0l.lithiumcat@nat.rebma.instinctive.eu>

On 14-05-18 01:32 AM, Natasha Kerensikova wrote:
> The problem is, how to terminate cleanly the worker tasks in a
> non-Ravenscar environment when the main application is completed?
>
>  From my understanding of ARM 9.3, I need a terminate alternative in the
> worker tasks. But those can only exist in selective accepts, so I have
> to turn things around and make the task wait for one of its entries to
> be called, rather than wait for an external protected entry.
>
> But then, how can a worker task entry be used to solve my problem? A
> protected operation cannot call a task entry, because it's potentially
> blocking. The job generator cannot call the entry directly, because it
> would block when the task is not ready, so I still need a queue between
> the generator and the worker task.

A protected entry can however requeue to a task entry.

I was faced with a similar problem in the non-Ravenscar task pools in 
Paraffin.

I did not want the programmer to have to call some protected subprogram 
to trigger the task pool to terminate. I also did not want to have to 
wait for a timeout to expire before the application could exit. I wanted 
it to be immediate.

So in your example, it might look something like;

package body Example is

    function Create_Job return Job_Description is
       Result : Job_Description;
    begin
       return Result;
    end Create_Job;

    procedure Enqueue_Job (Job : in Job_Description) is
    begin
       Queue.Append (Job);
    end Enqueue_Job;

    protected body Queue is
       entry Append (Job : in Job_Description) when True is
       begin
          if not Idle then
             requeue Worker.Work_Queued;
          else
             List.Append (Job);
          end if;
       end Append;

       procedure Get_Next (Job : out Job_Description) is
       begin
          Job := List.First_Element;
          List.Delete_First;
       end Get_Next;

       function Is_Empty return Boolean is
       begin
          return List.Is_Empty;
       end Is_Empty;

       procedure Worker_Idle is
       begin
          Idle := True;
       end Worker_Idle;

       function Worker_Is_Idle return Boolean is
       begin
          return Idle;
       end Worker_Is_Idle;

    end Queue;

    task body Worker is
       Job : Job_Description;
    begin
       loop
          begin

             Queue.Worker_Idle;

             if not Queue.Is_Empty then
                Queue.Get_Next (Job);
             else

                select
                   accept Work_Queued (Next_Job : Job_Description) do
                      Job := Next_Job;
                   end Work_Queued;

                or
                   terminate;
                end select;
             end if;

             --  <actually to the job>

          end;
       end loop;
    end Worker;
end Example;

Brad

> Thanks in advance for your help,
> Natasha
>

  parent reply	other threads:[~2014-05-18 23:05 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-18  7:32 Termination of tasks waiting on a protected queue Natasha Kerensikova
2014-05-18  9:24 ` anon
2014-05-18 19:43   ` Natasha Kerensikova
2014-05-18 17:16 ` Jeffrey Carter
2014-05-18 19:54   ` Natasha Kerensikova
2014-05-18 21:54     ` Jeffrey Carter
2014-05-18 18:42 ` sbelmont700
2014-05-18 18:48   ` Jeffrey Carter
2014-05-18 20:51     ` sbelmont700
2014-05-18 21:44       ` Jeffrey Carter
2014-05-19 21:49   ` Randy Brukardt
2014-05-20  7:54     ` Dmitry A. Kazakov
2014-05-20  7:58       ` Dmitry A. Kazakov
2014-05-18 23:05 ` Brad Moore [this message]
2014-05-19  7:28   ` Natasha Kerensikova
2014-05-27 11:08   ` Alejandro R. Mosteo
2014-05-28  1:04     ` Brad Moore
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox