* Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task?
@ 2016-09-01 15:43 Some Dude
2016-09-01 16:05 ` J-P. Rosen
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Some Dude @ 2016-09-01 15:43 UTC (permalink / raw)
I have a task with entries Start, Stop, Send, Close and an else clause that does some main processing when none of the entries are processed. So the structure is (very simplified):
task body Connection_Handler is
Done : Boolean := False;
begin
accept Start (Socket : Socket_Type) do
-- do this first
end Start;
loop
select when not Done =>
accept Stop do
Done := True;
end Stop;
or when not Done =>
accept Send (Socket : Socket_Type; Command : Command_Type) do
-- do something
end Send;
or when not Done =>
accept Close (Socket : Socket_Type) do
-- do something
end Close;
else
if not Done then
-- receive data if necessary using GNAT.sockets.Check_Selector
-- while no data is sent
end if;
end select;
exit when Done;
end loop;
end Connection_Handler;
However, when Stop is called and Done set to True, I get
raised TASKING_ERROR : s-tasren.adb:445
as an exception in my AUnit test harness and the test ends prematurely with an error code. This occurs in the main program task, or at least if I add a catch-all exception handler in the above task body, it is *not* triggered there.
I thought this occurs perhaps because there is no terminate alternative, but if I add:
or terminate;
before the else part, I get the error message "else part not allowed with other alternatives". So this is not possible.
Is there a way to stop the task gracefully (without abort) but also do some continuous processing like in the else part? Does anybody have an idea what might cause this error?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task?
2016-09-01 15:43 Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task? Some Dude
@ 2016-09-01 16:05 ` J-P. Rosen
2016-09-01 16:10 ` Dmitry A. Kazakov
2016-09-01 21:30 ` Some Dude
2 siblings, 0 replies; 4+ messages in thread
From: J-P. Rosen @ 2016-09-01 16:05 UTC (permalink / raw)
Le 01/09/2016 à 17:43, Some Dude a écrit :
Small remark: you can get rid of "Done":
task body Connection_Handler is
begin
accept Start (Socket : Socket_Type) do
-- do this first
end Start;
loop
select
accept Stop;
exit;
or
accept Send (Socket : Socket_Type; Command : Command_Type) do
-- do something
end Send;
or
accept Close (Socket : Socket_Type) do
-- do something
end Close;
else
-- receive data if necessary using GNAT.sockets.Check_Selector
-- while no data is sent
end select;
end loop;
end Connection_Handler;
> However, when Stop is called and Done set to True, I get
>
> raised TASKING_ERROR : s-tasren.adb:445
Presumably, this is due to some other task trying to rendezvous with
Connection_Handler after it has completed.
--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task?
2016-09-01 15:43 Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task? Some Dude
2016-09-01 16:05 ` J-P. Rosen
@ 2016-09-01 16:10 ` Dmitry A. Kazakov
2016-09-01 21:30 ` Some Dude
2 siblings, 0 replies; 4+ messages in thread
From: Dmitry A. Kazakov @ 2016-09-01 16:10 UTC (permalink / raw)
On 2016-09-01 17:43, Some Dude wrote:
> I have a task with entries Start, Stop, Send, Close and an else
> clause that does some main processing when none of the entries are processed.
> So the structure is (very simplified):
>
> task body Connection_Handler is
> Done : Boolean := False;
> begin
> accept Start (Socket : Socket_Type) do
> -- do this first
> end Start;
> loop
> select when not Done =>
> accept Stop do
> Done := True;
> end Stop;
> or when not Done =>
> accept Send (Socket : Socket_Type; Command : Command_Type) do
> -- do something
> end Send;
> or when not Done =>
> accept Close (Socket : Socket_Type) do
> -- do something
> end Close;
> else
> if not Done then
> -- receive data if necessary using GNAT.sockets.Check_Selector
> -- while no data is sent
> end if;
> end select;
> exit when Done;
> end loop;
> end Connection_Handler;
>
> However, when Stop is called and Done set to True, I get
>
> raised TASKING_ERROR : s-tasren.adb:445
Because the task is terminated Done = True, obviously.
The design is flawed. You cannot accept anything when sitting in
Check_Selector.
An alternative design is (very simplified):
loop
-- fill socket sets, checking selector ruins them
Check_Selector (...); -- with some reasonable timeout
case Status is
when Completed =>
-- Service read/write sockets
when Aborted | Timeout =>
-- service task messages queue
...
end case;
end loop;
No rendezvous, you push a message into a queue and then abort selector
which falls into Status Aborted which gives the task an opportunity to
inspect the queue.
Then you need not Send entry/message. Sending is driven by write socket
events. So when the socket is ready to be written Status = Completed and
the socket is in the write set, you send another portion of data from
the output ring buffer. Note that you need the buffer in any case
because you don't know how much the socket is ready to accept.
You don't interrupt the task for writing the buffer. It can be done
asynchronously.
P.S. You can find an example of working design in Simple Components:
http://www.dmitry-kazakov.de/ada/components.htm#multiple_GNAT.Sockets.Servers
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task?
2016-09-01 15:43 Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task? Some Dude
2016-09-01 16:05 ` J-P. Rosen
2016-09-01 16:10 ` Dmitry A. Kazakov
@ 2016-09-01 21:30 ` Some Dude
2 siblings, 0 replies; 4+ messages in thread
From: Some Dude @ 2016-09-01 21:30 UTC (permalink / raw)
I've found a solution similar to Dmitry's suggestion by using a protected object. The error no longer occurs and it's even faster.
Thanks a lot!
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-09-01 21:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-01 15:43 Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task? Some Dude
2016-09-01 16:05 ` J-P. Rosen
2016-09-01 16:10 ` Dmitry A. Kazakov
2016-09-01 21:30 ` Some Dude
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox