From: "Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org>
Subject: Re: Running a background task
Date: Fri, 16 May 2008 00:16:05 GMT
Date: 2008-05-16T00:16:05+00:00 [thread overview]
Message-ID: <9n4Xj.111458$TT4.6745@attbi_s22> (raw)
In-Reply-To: <f47b5be0-7488-439e-903a-d16cbd4116f2@z24g2000prf.googlegroups.com>
Bender wrote:
> Hi, I'm pretty new to Ada, and need to figure out a way to kick off a
> background task that runs more or less forever, while normal execution
> of the program continues.
>
> Thus far I've figured out how to create a task and start it, but the
> procedure calling it requires the task to finish before continuing
> on. I'm sure I just must be using the wrong mechanisms, but I can't
> really figure out the answer.
>
> Task definition
> ---------------------
> (spec)
> task type Poll_For_Status is
> entry On_String (String : in SideAB)
1. You're missing the terminator semicolon.
2. It's generally not a good idea to reuse the identifier "String", since it
hides the predefined type String, which will cause confusing error msgs if you
ever try to use that type.
> end Poll_For_Status;
>
> type Task_Access is access Poll_For_Status;
> Status_Task : Task_Access;
You have no need for the access type. You can simply say
Status_Task : Poll_For_Status;
Status_Task won't do anything, since it waits for a call to On_String.
You can simplify this even more by saying
task Status_Task is
entry On_String (...);
end Status_Task;
This assumes that Status_Task is the only instance of Poll_For_Status.
>
> (body)
> task body Poll_For_Status is
> begin
> accept On_String (String : in SideAB) do
> loop
> delay 3.0
Another missing terminator semicolon.
> Send_Status_Req (String);
> end loop;
This infinite loop is inside the accept for On_String, which means the task that
calls On_String will be blocked indefinitely.
> end On_String;
> end Poll_For_Status;
>
> Calling procedure
> ------------------------
> procedure Handle_Msg(...) is
> String : SideAB;
> ...
> begin
> ...
> Status_Task := new Poll_For_Status
As mentioned above, this is unneeded. And it's missing the terminator semicolon.
> Status_Task.On_String (String);
> ...
>
> If I remove the loop in the task body, it works fine. Putting it in
> seems to halt execution.
>
> Am I missing anything?
My comment on the loop inside the accept is what's confusing you. A rendezvous
(when a task calls another task's entry) blocks the calling task until it
completes. Since you have an infinite loop inside the accept, the rendezvous
never completes and Handle_Msg never returns from the call to On_String.
Possible solutions include
1. Having the task store the value passed to it:
Side : Sideab;
begin -- Poll_For_Status;
accept On_String (String : in Sideab) do
Side := String;
end On_String;
loop
...
2. Communicating via a protected object rather than a rendezvous. This is a
bigger change, but depending on your needs might result in a better design.
It may not be important to you, but your loop does not execute every 3 seconds.
There may be some time after the delay expires before the task starts executing
again, and using "delay" allows those times to accumulate; there's also the time
to call the subprogram. If you want it to be as close to every 3 seconds as you
can get, you should use the "delay until" statement.
--
Jeff Carter
"Many times we're given rhymes that are quite unsingable."
Monty Python and the Holy Grail
57
next prev parent reply other threads:[~2008-05-16 0:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-15 20:51 Running a background task Bender
2008-05-15 22:31 ` Adam Beneschan
2008-05-15 23:14 ` Adam Beneschan
2008-05-16 0:43 ` Bender
2008-05-16 15:25 ` Adam Beneschan
2008-05-16 15:29 ` Adam Beneschan
2008-05-16 0:16 ` Jeffrey R. Carter [this message]
2008-05-16 0:49 ` Bender
2008-05-16 4:32 ` Jeffrey R. Carter
2008-05-16 14:34 ` Bender
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox