Handle a signal

From Rosetta Code
Revision as of 00:25, 23 December 2008 by rosettacode>Waldorf (Task Definition)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Handle a signal
You are encouraged to solve this task according to the task description, using any language you may know.

Most general purpose operating systems provide interrupt facilities, sometimes called signals. Unhandled signals generally terminate a program in a disorderly manner. Signal handlers are created so that the program behaves in a well-defined manner upon receipt of a signal.

For this task you will provide a program that displays a single integer on each line of output at the rate of one integer in each half second. Upon receipt of the SigInt signal (often created by the user typing ctrl-C) the program will cease printing integers to its output, print the number of seconds the program has run, and then the program will terminate.

Ada

Signal Handler

Ada signal handlers must be defined at the library level. The following package defines a simple signal handler for the SigInt signal. <ada> with Ada.Interrupts; use Ada.Interrupts; with Ada.Interrupts.Names; use Ada.Interrupts.Names;

package Sigint_Handler is

     protected Handler is
     entry Wait;
     procedure Handle;
     pragma Interrupt_Handler(Handle);
     pragma Attach_Handler(Handle, Sigint);
     private
     Call_Count : Natural := 0;
  end Handler;

end Sigint_Handler; </ada> <ada> package body Sigint_Handler is

  -------------
  -- Handler --
  -------------
  protected body Handler is
     ----------
     -- Wait --
     ----------
     entry Wait when Call_Count > 0 is
     begin
        Call_Count := Call_Count - 1;
     end Wait;
     ------------
     -- Handle --
     ------------
     procedure Handle is
     begin
        Call_Count := Call_Count + 1;
     end Handle;
  end Handler;

end Sigint_Handler; </ada> A signal may be received at any time in a program. Ada signal handling requires a task to suspend on an entry call for the handler which is executed only when the signal has been received. The following program uses the interrupt handler defined above to deal with receipt of SigInt. <ada> with Ada.Calendar; use Ada.Calendar; with Ada.Text_Io; use Ada.Text_Io; with Sigint_Handler; use Sigint_Handler;

procedure Signals is

  task Counter is
     entry Stop;
  end Counter;
  task body Counter is
     Current_Count : Natural := 0;
  begin
     loop
        select
           accept Stop;
           exit;
        or delay 0.5;
        end select;
        Current_Count := Current_Count + 1;
        Put_Line(Natural'Image(Current_Count));
     end loop;
  end Counter;
  task Sig_Handler;
  
  task body Sig_Handler is
     Start_Time : Time := Clock;
     Sig_Time : Time;
  begin
     Handler.Wait;
     Sig_Time := Clock;
     Counter.Stop;
     Put_Line("Program execution took" & Duration'Image(Sig_Time - Start_Time) & " seconds");
  end Sig_Handler;
     

begin

  null;
        

end Signals; </ada>

Sample Output

 1
 2
 3
 4
 5
 6
 7
 8
Program execution took 4.348057086 seconds