Possible language changes
Jim Rogers
jimmaureenrogers at att.net
Fri Mar 4 01:56:53 GMT 2005
----- Original Message -----
From: "Douglas C. Schmidt" <schmidt at dre.vanderbilt.edu>
> /**
> * Send @a signum to @a thread_id. Not supported on platforms
> * that do not have advanced signal support, such as Win32.
> * Can throw various exceptions on failure (TBD).
> */
> void signal (thread_t thread_id,
> int signum);
Your signal handling example above requires advanced signal support.
Do you have a more generalized solution to signal handling in a threaded
application? For instance, what would you provide for Win32? It is
certainly a platform which cannot currently be ignored.
Ada treats all signal handling as a concurrent processing situation.
Interrupts are handled through the creation of a protected object
designated as an interrupt handler. An interrupt (signal) is associated
with a parameterless procedure in that protected object.
A task is then created that calls an entry on the same protected object
and suspends until an interrupt is received by the protected object.
The following simple example demonstrates how Ada can capture
interrupt.
with Ada.Interrupts.Names;
use Ada.Interrupts.Names;
package Handlers is
pragma Unreserve_All_Interrupts;
-- Declare a protected object to handle SIGINT
protected Handler is
procedure Counter;
entry Wait_For_Interrupt;
pragma Attach_Handler(Counter,Sigint);
private
Count : Natural := 0;
end Handler;
-- Declare a task to wait for signal to be handled
task Int_Handler is
entry Stop;
end Int_Handler;
end Handlers;
with Ada.Text_Io;
use Ada.Text_Io;
package body Handlers is
-- Define the signal handler protected object
protected body Handler is
procedure Counter is
begin
Count := Count + 1;
end Counter;
entry Wait_For_Interrupt when Count > 0 is
begin
Count := Count - 1;
end Wait_For_Interrupt;
end Handler;
-- Define the task that will respond to signals
task body Int_Handler is
Num_Interrupts : Natural := 0;
begin
loop
select
Handler.Wait_For_Interrupt;
Num_Interrupts := Num_Interrupts + 1;
Put_Line("handled interrupt #" &
Natural'Image(Num_Interrupts));
or
delay 0.001;
select
accept Stop;
exit;
or
delay 0.0;
end select;
end select;
end loop;
end Int_Handler;
end Handlers;
-----------------------------------------------------------------------
-- Interrupt Demonstration
-- This program declares a dependency upon the signal handler defined
-- in the Handlers package. This will cause the handler protected object
-- and the int_handler task to be started.
-----------------------------------------------------------------------
with Ada.Text_Io;
with Handlers;
procedure Sig_Handler is
begin
for Num in 1..20 loop
Ada.Text_Io.Put_Line("Iteration" & Integer'Image(Num));
delay 1.0;
end loop;
-- shut down the int_handler task
Handlers.Int_Handler.Stop;
end Sig_Handler;
The procedure Sig_Handler in this program is equivalent to a "main" in
C++. Sig_Handler simply prints out a line once per second indicating
the number of times it has gone through its "for" loop. Sig_Handler calls
the Stop entry for the Int_Handler task defined in the Handlers package
when the loop completes.
Every time the program receives a SIGINT the protected procedure
Handlers.Counter is called, incrementing the Count data member of
the Handlers protected object. The Int_Handler task suspends on its
call to the entry Handlers.Wait_For_Interrupt until the Count data
member contains a value > 0.
The example above is actually a bit more sophisticated than that.
It calls the entry and suspends for no more than 0.001 seconds.
If no interrupt is received within the 0.001 second time period the
program checks to see if the Stop entry for the task has been called.
If the Stop entry has been called the task exits its loop and terminates.
If an interrupt has been received within the specified 0.001 seconds the
task handles the interrupt then loops back to call Wait_For_Interrupt
again.
As soon as the procedure Handlers.Counter completes, the boundary
condition for Handlers.Wait_For_Interrupt is re-evaluated and Counter
is decremented.
This approach allows the system to respond to interrupts even when
they are received faster than the handler can handle an individual
interrupt.
Jim Rogers
More information about the cpp-threads
mailing list