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=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Rendezvous with select ... else and "or terminate" not possible - but how do I quit this task? Date: Thu, 1 Sep 2016 18:10:51 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <6e4d6fc1-dcb9-454a-8c1e-df090224438e@googlegroups.com> NNTP-Posting-Host: 4UnmtEBiFcCZzQad+30FUw.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:31678 Date: 2016-09-01T18:10:51+02:00 List-Id: 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