From: Reto Buerki on
Hi all,

Before reporting a bug, I wanted to ask your opinion on this. Consider
the following code:

--

with Ada.Real_Time.Timing_Events;

package Timers is

use Ada.Real_Time.Timing_Events;

protected type Timer_Type is
procedure Setup (At_Time : Ada.Real_Time.Time);
function Get_Time return Ada.Real_Time.Time;
procedure Stop (Status : out Boolean);
private
procedure Handle (Event : in out Timing_Event);

Event : Timing_Event;
end Timer_Type;

end Timers;

--

package body Timers is

protected body Timer_Type is

function Get_Time return Ada.Real_Time.Time is
begin
return Event.Time_Of_Event;
end Get_Time;

procedure Handle (Event : in out Timing_Event) is
begin
null;
end Handle;

procedure Setup (At_Time : Ada.Real_Time.Time) is
begin
Event.Set_Handler (At_Time => At_Time,
Handler => Handle'Access);
end Setup;

procedure Stop (Status : out Boolean) is
begin
Event.Cancel_Handler (Cancelled => Status);
end Stop;

end Timer_Type;

end Timers;

--

with Ada.Text_IO;
with Ada.Real_Time;

with Timers;

procedure Cancel_Handler is
use Ada.Real_Time;

Handler : Timers.Timer_Type;
Timer : constant Time := Clock + Minutes (60);
begin
if Handler.Get_Time = Time_First then
Ada.Text_IO.Put_Line ("Time is Time_First ...");
end if;

Handler.Setup (At_Time => Timer);
if Handler.Get_Time = Timer then
Ada.Text_IO.Put_Line ("Handler set ...");
end if;

declare
Stopped : Boolean := False;
begin
Handler.Stop (Status => Stopped);

if Stopped then
Ada.Text_IO.Put_Line ("Timer cancelled ...");
if Handler.Get_Time = Timer then
Ada.Text_IO.Put_Line ("Why is the time still set then?");
end if;
end if;
end;

end Cancel_Handler;

--

The 'Timers' package provides a simple protected type 'Timer_Type' which
basically just wraps an Ada.Real_Time.Timing_Events.Timing_Event type.
The Setup() procedure can be used to set a specific event time.

Stop() just calls the Cancel_Handler() procedure of the internal
Timing_Event. This procedure 'clears' the event (if it is set).

Ada RM D.15 about Real_Time.Timing Events states:

9/2 An object of type Timing_Event is said to be set if it is associated
with a non-null value of type Timing_Event_Handler and cleared
otherwise. All Timing_Event objects are initially cleared.

17/2 The procedure Cancel_Handler clears the event if it is set.
Cancelled is assigned True if the event was set prior to it being
cleared; otherwise it is assigned False.

18/2 The function Time_Of_Event returns the time of the event if the
event is set; otherwise it returns Real_Time.Time_First.

The RM does not explicitly state what happens with the event time value
associated with a specific event after a call to Cancel_Handler(), but
it seems logical to assume that Time_Of_Event should return Time_First
again because no event is 'set' after it has been cleared (handler set
to 'null').

With FSF GNAT, only the event handler is cleared, the event time remains
set. Tested with GNAT 4.3.2 and 4.4.1 on Debian Stable/SID.

Could this be considered as a bug?

Thanks!
- reto
From: Anh Vo on
On Sep 14, 9:12 am, Reto Buerki <r...(a)codelabs.ch> wrote:
> Hi all,
>
> Before reporting a bug, I wanted to ask your opinion on this. Consider
> the following code:
>
> --
>
> with Ada.Real_Time.Timing_Events;
>
> package Timers is
>
>    use Ada.Real_Time.Timing_Events;
>
>    protected type Timer_Type is
>       procedure Setup (At_Time : Ada.Real_Time.Time);
>       function Get_Time return Ada.Real_Time.Time;
>       procedure Stop (Status : out Boolean);
>    private
>       procedure Handle (Event : in out Timing_Event);
>
>       Event : Timing_Event;
>    end Timer_Type;
>
> end Timers;
>
> --
>
> package body Timers is
>
>    protected body Timer_Type is
>
>       function Get_Time return Ada.Real_Time.Time is
>       begin
>          return Event.Time_Of_Event;
>       end Get_Time;
>
>       procedure Handle (Event : in out Timing_Event) is
>       begin
>          null;
>       end Handle;
>
>       procedure Setup (At_Time : Ada.Real_Time.Time) is
>       begin
>          Event.Set_Handler (At_Time => At_Time,
>                             Handler => Handle'Access);
>       end Setup;
>
>       procedure Stop (Status : out Boolean) is
>       begin
>          Event.Cancel_Handler (Cancelled => Status);
>       end Stop;
>
>    end Timer_Type;
>
> end Timers;
>
> --
>
> with Ada.Text_IO;
> with Ada.Real_Time;
>
> with Timers;
>
> procedure Cancel_Handler is
>    use Ada.Real_Time;
>
>    Handler : Timers.Timer_Type;
>    Timer   : constant Time := Clock + Minutes (60);
> begin
>    if Handler.Get_Time = Time_First then
>       Ada.Text_IO.Put_Line ("Time is Time_First ...");
>    end if;
>
>    Handler.Setup (At_Time => Timer);
>    if Handler.Get_Time = Timer then
>       Ada.Text_IO.Put_Line ("Handler set ...");
>    end if;
>
>    declare
>       Stopped : Boolean := False;
>    begin
>       Handler.Stop (Status => Stopped);
>
>       if Stopped then
>          Ada.Text_IO.Put_Line ("Timer cancelled ...");
>          if Handler.Get_Time = Timer then
>             Ada.Text_IO.Put_Line ("Why is the time still set then?");
>          end if;
>       end if;
>    end;
>
> end Cancel_Handler;
>
> --
>
> The 'Timers' package provides a simple protected type 'Timer_Type' which
> basically just wraps an Ada.Real_Time.Timing_Events.Timing_Event type.
> The Setup() procedure can be used to set a specific event time.
>
> Stop() just calls the Cancel_Handler() procedure of the internal
> Timing_Event. This procedure 'clears' the event (if it is set).
>
> Ada RM D.15 about Real_Time.Timing Events states:
>
> 9/2 An object of type Timing_Event is said to be set if it is associated
> with a non-null value of type Timing_Event_Handler and cleared
> otherwise. All Timing_Event objects are initially cleared.
>
> 17/2 The procedure Cancel_Handler clears the event if it is set.
> Cancelled is assigned True if the event was set prior to it being
> cleared; otherwise it is assigned False.
>
> 18/2 The function Time_Of_Event returns the time of the event if the
> event is set; otherwise it returns Real_Time.Time_First.
>
> The RM does not explicitly state what happens with the event time value
> associated with a specific event after a call to Cancel_Handler(), but
> it seems logical to assume that Time_Of_Event should return Time_First
> again because no event is 'set' after it has been cleared (handler set
> to 'null').
>
> With FSF GNAT, only the event handler is cleared, the event time remains
> set. Tested with GNAT 4.3.2 and 4.4.1 on Debian Stable/SID.
>
> Could this be considered as a bug?

I say it is a bug because ARM 18/2 is violated.

Anh Vo

From: Reto Buerki on
Anh Vo wrote:
> On Sep 14, 9:12 am, Reto Buerki <r...(a)codelabs.ch> wrote:

[...]

>> Could this be considered as a bug?
>
> I say it is a bug because ARM 18/2 is violated.

Thanks for the confirmation, bug filed [1].

- reto

[1] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41383