From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00,FREEMAIL_FROM, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 Path: border1.nntp.dca3.giganews.com!backlog3.nntp.dca3.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!aioe.org!.POSTED!not-for-mail From: anon@att.net Newsgroups: comp.lang.ada Subject: Re: Termination of tasks waiting on a protected queue Date: Sun, 18 May 2014 09:24:53 +0000 (UTC) Organization: Aioe.org NNTP Server Message-ID: References: Reply-To: anon@att.net NNTP-Posting-Host: +dqhME2ZLoY0VBSMBFWsJw.user.speranza.aioe.org X-Complaints-To: abuse@aioe.org X-Notice: Filtered by postfilter v. 0.8.2 X-Newsreader: IBM NewsReader/2 2.0 X-Original-Bytes: 4883 Xref: number.nntp.dca.giganews.com comp.lang.ada:186457 Date: 2014-05-18T09:24:53+00:00 List-Id: try using a Select / terminate statements task body Worker is Job : Job_Description; begin loop select Queue.Get_Next (Job); or terminate ; end select ; end loop; end Worker; In , Natasha Kerensikova writes: >Hello, > >I have been having a task termination issue, and I'm wondering whether I >got my design wrong or whether I'm missing something, so I ask you to >help me on that. > >The basic need is delegating potentially long jobs to a dedicated task >(or pool of tasks) so that the program flow generating the jobs and >continue quickly. I furthermore assume that the jobs are "fire and >forget", that there is no need to report anything about completion (or >lack of thereof) to the code that generated the jobs (or more >realistically, that reporting is performed through channels outside of >the scope of the problem). > >So I went with the basic design below: > > package Example is > type Job_Description is private; > > function Create_Job (...) return Job_Description; > procedure Enqueue_Job (Job : in Job_Description); > > private > > package Job_Lists is new Ada.Containers.Doubly_Linked_Lists > (Job_Description); > > protected Queue is > procedure Append (Job : in Job_Description); > entry Get_Next (Job : out Job_Description); > private > List : Job_Lists.List; > Has_Job : Boolean := False; > end Queue; > > task Worker is > end Worker; > end Example; > > package body Example is > procedure Enqueue_Job (Job : in Job_Description) is > begin > Queue.Append (Job); > end Enqueue_Job; > > protected body Queue is > procedure Append (Job : in Job_Description) is > begin > List.Append (Job); > Has_Job := True; > end Append; > > entry Get_Next (Job : out Job_Description) > when Has_Job is > begin > Job := List.First_Element; > List.Delete_First; > Has_Job := not List.Is_Empty; > end Get_Next; > end Queue; > > task body Worker is > Job : Job_Description; > begin > loop > Queue.Get_Next (Job); > > end loop; > end Worker; > end Example; > >As you might have guessed, I have recently read a lot of material about >Ravenscar profile, and as far as I can tell this example does match the >profile, even though the original need happens in a much more relaxed >environment. > >For example, without Ravenscar restrictions, the Worker task could >easily be turned into a task type, and use an array of them to >implement a pool of workers. > >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. > >Alternatively, I could use a special value for Job_Description (or a new >out parameter) to make the worker exit its infinite loop, and somehow >make the protect Queue object aware that the master is completed, so >that it can signal the worker task(s) to complete. But how can this be >implemented? Since the tasks block the finalization of the master, I >can't rely on a Finalize procedure to notify the protected object. > > >Thanks in advance for your help, >Natasha