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!mx02.eternal-september.org!feeder.eternal-september.org!news.swapon.de!newsfeed.fsmpi.rwth-aachen.de!newsfeed.straub-nv.de!feeder.erje.net!2.us.feeder.erje.net!news.glorb.com!news.netfront.net!not-for-mail From: "T.G." Newsgroups: comp.lang.ada Subject: Re: Abortable Timed Action Date: Fri, 8 Jan 2016 20:24:31 +0000 (UTC) Organization: Netfront http://www.netfront.net/ Message-ID: References: <446ae62f-6b95-4a4f-b253-85af071b6bf6@googlegroups.com> NNTP-Posting-Host: 91.121.158.17 X-Trace: adenine.netfront.net 1452284671 9951 91.121.158.17 (8 Jan 2016 20:24:31 GMT) X-Complaints-To: news@netfront.net NNTP-Posting-Date: Fri, 8 Jan 2016 20:24:31 +0000 (UTC) User-Agent: slrn/1.0.2 (Linux) Xref: news.eternal-september.org comp.lang.ada:29059 Date: 2016-01-08T20:24:31+00:00 List-Id: On 2016-01-06, Anh Vo wrote: > After looking at your original post again, I believe your code > should work after replacing delay statement by delay until > statement. The delay until statement does not have time drifting > issue. In addition, then Entry Finish can be replaced by the > terminate alternative. The modified version is shown below. > select > accept Cancel; > or > delay until (Ada.Calendar.Clock + Timeout); > Put_Line ("Do Something"); > end select; The reason why I had an explicit Finish instead of using terminate was that I was thinking of creating the timer dynamically and then freeing it with Ada.Unchecked_Deallocation. So I wanted to Finish the task before freeing it. I'm not sure if calling Free on an access actually terminates the task Normally. delay until is an interesting idea. I'm assuming that time drift would be an issue in periodic actions that repeat at a certain interval, but in that case delay until could also have issues if it loses some accuracy on each iteration. For example, modifying the code to run periodically, with: Start_Time : Ada.Calendar.Time; begin ... accept Exec_After (T : Duration) do Start_Time := Ada.Calendar.Clock; Timeout := T; end Exec_After; Inner : loop select accept Cancel; exit Inner; or delay until (Ada.Calendar.Clock + Timeout); Put_Line (Duration'Image (Ada.Calendar.Clock - Start_Time)); end select; end loop Inner; it will drift, however, we can still use delay until but with a counter, for example: task body Timed_Action_Task is Timeout : Duration; Start_Time : Ada.Calendar.Time; Counter : Positive := 1; begin loop select accept Exec_After (T : Duration) do Start_Time := Ada.Calendar.Clock; Timeout := T; Counter := 1; end Exec_After; Inner : loop select exit Inner; accept Cancel; or delay until (Start_Time + (Timeout * Counter)); Counter := Counter + 1; Put_Line (Duration'Image (Ada.Calendar.Clock - Start_Time)); end select; end loop Inner; or terminate; end select; end loop; end Timed_Action_Task; This avoids the drift from the previous example. In my actual code, I used Ada.Real_Time.Timing_Events. It ended up being somewhat complicated, but only because I wanted to pass both Action and User_Data to the Timer and make a more flexible/reusable timer. Now after testing the code above, I think I want to recheck my code for a possible time drift with periodic timed events. --- news://freenews.netfront.net/ - complaints: news@netfront.net ---