Created
August 21, 2012 07:14
-
-
Save msiedlarek/3413017 to your computer and use it in GitHub Desktop.
Socket server terminating on interrupt in Ada
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with Ada.Interrupts; | |
with Ada.Interrupts.Names; | |
with Servers; | |
package body Application is | |
pragma Interrupt_State ( | |
Name => Ada.Interrupts.Names.SIGINT, | |
State => USER | |
); | |
Server : Servers.Server; | |
protected Interrupt_Handler is | |
procedure Handle | |
with Interrupt_Handler; | |
end Interrupt_Handler; | |
procedure Run | |
is | |
begin | |
Ada.Interrupts.Attach_Handler ( | |
Interrupt_Handler.Handle'Access, | |
Ada.Interrupts.Names.SIGINT | |
); | |
Servers.Start (Server); | |
end Run; | |
protected body Interrupt_Handler is | |
procedure Handle is begin | |
Servers.Stop (Server); | |
end Handle; | |
end Interrupt_Handler; | |
end Application; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Application is | |
procedure Run; | |
end Application; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with Application; | |
procedure Main | |
is | |
begin | |
Application.Run; | |
end Main; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with Ada.Text_IO; | |
package body Servers is | |
procedure Start | |
(S : in out Server) | |
is | |
use type GNAT.Sockets.Selector_Status; | |
Listener_Socket : GNAT.Sockets.Socket_Type; | |
Listener_Address : constant GNAT.Sockets.Sock_Addr_Type := ( | |
Family => GNAT.Sockets.Family_Inet, | |
Addr => GNAT.Sockets.Inet_Addr ("127.0.0.1"), | |
Port => 4000 | |
); | |
Client_Socket : GNAT.Sockets.Socket_Type; | |
Client_Address : GNAT.Sockets.Sock_Addr_Type; | |
Selector_Status : GNAT.Sockets.Selector_Status; | |
begin | |
GNAT.Sockets.Create_Socket (Listener_Socket); | |
GNAT.Sockets.Set_Socket_Option ( | |
Socket => Listener_Socket, | |
Level => GNAT.Sockets.Socket_Level, | |
Option => ( | |
Name => GNAT.Sockets.Reuse_Address, | |
Enabled => True | |
) | |
); | |
GNAT.Sockets.Bind_Socket ( | |
Socket => Listener_Socket, | |
Address => Listener_Address | |
); | |
GNAT.Sockets.Listen_Socket (Listener_Socket); | |
Ada.Text_IO.Put_Line ( | |
"Listening on " & GNAT.Sockets.Image (Listener_Address) | |
); | |
loop | |
GNAT.Sockets.Accept_Socket ( | |
Server => Listener_Socket, | |
Socket => Client_Socket, | |
Address => Client_Address, | |
Timeout => GNAT.Sockets.Forever, | |
Selector => S.Accepting_Selector'Access, | |
Status => Selector_Status | |
); | |
exit when Selector_Status = GNAT.Sockets.Aborted; | |
if Selector_Status = GNAT.Sockets.Completed then | |
Ada.Text_IO.Put_Line ( | |
"Client from " & GNAT.Sockets.Image (Client_Address) | |
); | |
String'Write ( | |
GNAT.Sockets.Stream (Client_Socket), | |
"Hello!" & ASCII.CR & ASCII.LF | |
); | |
GNAT.Sockets.Close_Socket (Client_Socket); | |
end if; | |
end loop; | |
GNAT.Sockets.Close_Socket (Listener_Socket); | |
end Start; | |
procedure Stop | |
(S : in out Server) | |
is | |
begin | |
Ada.Text_IO.Put_Line (""); | |
Ada.Text_IO.Put_Line ("Stopping..."); | |
GNAT.Sockets.Abort_Selector (S.Accepting_Selector); | |
end Stop; | |
overriding | |
procedure Initialize | |
(Object : in out Server) | |
is | |
begin | |
GNAT.Sockets.Create_Selector (Object.Accepting_Selector); | |
end Initialize; | |
overriding | |
procedure Finalize | |
(Object : in out Server) | |
is | |
begin | |
GNAT.Sockets.Close_Selector (Object.Accepting_Selector); | |
end Finalize; | |
end Servers; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with Ada.Finalization; | |
with GNAT.Sockets; | |
package Servers is | |
type Server is new Ada.Finalization.Limited_Controlled with private; | |
procedure Start | |
(S : in out Server); | |
procedure Stop | |
(S : in out Server); | |
private | |
type Server is new Ada.Finalization.Limited_Controlled with record | |
Accepting_Selector : aliased GNAT.Sockets.Selector_Type; | |
end record; | |
overriding | |
procedure Initialize | |
(Object : in out Server); | |
overriding | |
procedure Finalize | |
(Object : in out Server); | |
end Servers; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment