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
ExitingThis 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.