D.15 Timing Events
This subclause describes a language-defined package 
to allow user-defined protected procedures to be executed at a specified 
time without the need for a task or a delay statement. 
Static Semantics
The following language-defined 
library package exists: 
package Ada.Real_Time.Timing_Events 
is 
  type Timing_Event 
is tagged limited private;
  
type Timing_Event_Handler
       
is access protected procedure (Event : 
in out Timing_Event);
 
  procedure Set_Handler (Event   : 
in out Timing_Event;
                         At_Time : 
in Time;
                         Handler : 
in Timing_Event_Handler);
  
procedure Set_Handler (Event   : 
in out Timing_Event;
                         In_Time : 
in Time_Span;
                         Handler : 
in Timing_Event_Handler);
  
function Current_Handler (Event : Timing_Event)
       
return Timing_Event_Handler;
  
procedure Cancel_Handler (Event     : 
in out Timing_Event;
                            Cancelled : 
out Boolean);
 
  function Time_Of_Event (Event : Timing_Event) 
return Time;
 
private
  ... -- not specified by the language
end Ada.Real_Time.Timing_Events;
The type Timing_Event represents a time in the future 
when an event is to occur. The type Timing_Event needs finalization
 
(see 
7.6).
 
An object of type Timing_Event is said to be 
set 
if it is associated with a nonnull value of type Timing_Event_Handler 
and 
cleared otherwise. All Timing_Event objects are initially 
cleared. 
 
 The type Timing_Event_Handler identifies a protected 
procedure to be executed by the implementation when the timing event 
occurs. Such a protected procedure is called a 
handler. 
 
Dynamic Semantics
 The procedures Set_Handler associate the handler 
Handler with the event Event: if Handler is null, the event is 
cleared; otherwise, it is set. The first procedure Set_Handler sets the 
execution time for the event to be At_Time. The second procedure Set_Handler 
sets the execution time for the event to be Real_Time.Clock + In_Time.
 A call of a procedure Set_Handler for an event that 
is already set replaces the handler and the time of execution; if Handler 
is not null, the event remains set.
 As soon as possible after the time set for the event, 
the handler is executed, passing the event as parameter. The handler 
is only executed if the timing event is in the set state at the time 
of execution. The initial action of the execution of the handler is to 
clear the event.
 If the Ceiling_Locking policy (see 
D.3) 
is in effect when a procedure Set_Handler is called, a check is made 
that the ceiling priority of Handler.
all is Interrupt_Priority'Last. 
If the check fails, Program_Error is raised.
 
 If a procedure Set_Handler is called with zero or 
negative In_Time or with At_Time indicating a time in the past, then 
the handler is executed as soon as possible after the completion of the 
call of Set_Handler.
 The function Current_Handler returns the handler 
associated with the event Event if that event is set; otherwise, it returns 
null.
 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.
 The function Time_Of_Event returns the time of the 
event if the event is set; otherwise, it returns Real_Time.Time_First.
 As part of the finalization of an object of type 
Timing_Event, the Timing_Event is cleared.
 If several timing events are set for the same time, 
they are executed in FIFO order of being set.
 An exception propagated from a handler invoked by 
a timing event has no effect.
Implementation Requirements
 For a given Timing_Event object, the implementation 
shall perform the operations declared in this package atomically with 
respect to any of these operations on the same Timing_Event object. The 
replacement of a handler by a call of Set_Handler shall be performed 
atomically with respect to the execution of the handler.
Metrics
 The implementation 
shall document the following metric: 
An upper bound on the lateness of the execution 
of a handler. That is, the maximum time between the time specified for 
the event and when a handler is actually invoked assuming no other handler 
or task is executing during this interval.
Implementation Advice
 The protected handler procedure should be executed 
directly by the real-time clock interrupt mechanism.
48  Since a call of Set_Handler is not a 
potentially blocking operation, it can be called from within a handler.
49  A Timing_Event_Handler can be associated 
with several Timing_Event objects.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe