Signals in Ada
Here’s the translation of the Go code to Ada, formatted in Markdown suitable for Hugo:
Our program demonstrates how to handle Unix signals in Ada. For example, we might want a server to gracefully shutdown when it receives a SIGTERM
, or a command-line tool to stop processing input if it receives a SIGINT
. Here’s how to handle signals in Ada using tasks and protected objects.
with Ada.Text_IO;
with Ada.Interrupts.Names;
with Ada.Synchronous_Task_Control;
procedure Signals is
use Ada.Text_IO;
use Ada.Synchronous_Task_Control;
Done : Suspension_Object;
protected Signal_Handler is
procedure Handle;
pragma Interrupt_Handler (Handle);
pragma Attach_Handler (Handle, Ada.Interrupts.Names.SIGINT);
pragma Attach_Handler (Handle, Ada.Interrupts.Names.SIGTERM);
end Signal_Handler;
protected body Signal_Handler is
procedure Handle is
begin
Put_Line ("Received signal");
Set_True (Done);
end Handle;
end Signal_Handler;
task Signal_Waiter;
task body Signal_Waiter is
begin
Put_Line ("Awaiting signal");
Suspend_Until_True (Done);
Put_Line ("Exiting");
end Signal_Waiter;
begin
null;
end Signals;
Ada signal handling works by attaching interrupt handlers to protected procedures. We’ll create a protected object to handle the signals.
The Signal_Handler
protected object is defined with a Handle
procedure that is marked as an interrupt handler and attached to both SIGINT
and SIGTERM
.
We create a Suspension_Object
named Done
to coordinate between the signal handler and the main program flow.
The Signal_Waiter
task demonstrates a more realistic scenario of graceful shutdown. It waits for the Done
suspension object to be set to true, which happens when a signal is received.
In the Handle
procedure, we print a message indicating that a signal was received and set the Done
suspension object to true.
The Signal_Waiter
task prints “Awaiting signal”, then suspends until Done
is set to true. When it resumes, it prints “Exiting”.
When we run this program, it will block waiting for a signal. By typing ctrl-C
(which the terminal shows as ^C
) we can send a SIGINT
signal, causing the program to print “Received signal” and then “Exiting”.
$ gnatmake signals.adb
$ ./signals
Awaiting signal
^C
Received signal
Exiting
This example demonstrates how Ada can handle Unix signals using its built-in tasking and synchronization mechanisms, providing a robust way to manage program termination and other signal-driven events.