Refactor out the Epoll shim and incorporate async-ada as well.

This is still using the raw epoll interfaces in the main subprogram, but I would
like to see some nicer abstraction happen here.
This commit is contained in:
R. Tyler Croy 2019-01-06 11:19:30 -08:00
parent d972d64a11
commit 1bc7cf2008
No known key found for this signature in database
GPG Key ID: E5C92681BEF6CEA2
5 changed files with 25 additions and 98 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "contrib/logga"]
path = contrib/logga
url = https://git.brokenco.de/berriedale/logga.git
[submodule "contrib/async-ada"]
path = contrib/async-ada
url = https://git.brokenco.de/berriedale/async-ada.git

1
contrib/async-ada Submodule

@ -0,0 +1 @@
Subproject commit 1d94bae32747ab1dd1205d85a3e1ad30e0534e54

View File

@ -1,3 +1,4 @@
with "contrib/async-ada/async.gpr";
with "contrib/logga/logga.gpr";
project Mozzoni is

View File

@ -1,80 +0,0 @@
with GNAT.Sockets,
Interfaces.C,
System;
package Epoll is
subtype Epoll_Fd_Type is Integer;
subtype Epoll_Events_Type is Interfaces.Unsigned_32;
EPOLLIN : constant Epoll_Events_Type := 1;
EPOLLPRI : constant Epoll_Events_Type := 2;
EPOLLOUT : constant Epoll_Events_Type := 4;
EPOLLRDNORM : constant Epoll_Events_Type := 64;
EPOLLRDBAND : constant Epoll_Events_Type := 128;
EPOLLWRNORM : constant Epoll_Events_Type := 256;
EPOLLWRBAND : constant Epoll_Events_Type := 512;
EPOLLMSG : constant Epoll_Events_Type := 1024;
EPOLLERR : constant Epoll_Events_Type := 8;
EPOLLHUP : constant Epoll_Events_Type := 16;
EPOLLRDHUP : constant Epoll_Events_Type := 8192;
EPOLLEXCLUSIVE : constant Epoll_Events_Type := 268435456;
EPOLLWAKEUP : constant Epoll_Events_Type := 536870912;
EPOLLONESHOT : constant Epoll_Events_Type := 1073741824;
EPOLLET : constant Epoll_Events_Type := 2147483648;
type Epoll_Ctl_Type is (Epoll_Ctl_Add,
Epoll_Ctl_Del,
Epoll_Ctl_Mod);
for Epoll_Ctl_Type use (Epoll_Ctl_Add => 1,
Epoll_Ctl_Del => 2,
Epoll_Ctl_Mod => 3);
type Data_Type (Discriminant : Interfaces.C.unsigned := 0) is record
case Discriminant is
when 0 =>
Ptr : System.Address;
when 1 =>
FD : Epoll_Fd_Type;
when 2 =>
U32 : Interfaces.Unsigned_32;
when others =>
U64 : Interfaces.Unsigned_64;
end case;
end record
with Unchecked_Union,
Convention => C;
type Event_Type is record
Events : Interfaces.Unsigned_32;
Data : Data_Type;
end record
with Convention => C,
Pack;
type Event_Array_Type is array (Integer range <>) of aliased Event_Type
with Convention => C;
function Create (Size : Integer) return Epoll_Fd_Type
with Import,
Link_Name => "epoll_create",
Convention => C;
function Control (Epfd : Epoll_Fd_Type;
Op : Epoll_Ctl_Type;
Fd : Epoll_Fd_Type;
Events : access Event_Type) return Integer
with Import,
Link_Name => "epoll_ctl",
Convention => C;
function Wait (Epfd : Epoll_Fd_Type;
Events : Event_Array_Type;
Max_Events : Integer;
Timeout : Integer) return Integer
with Import,
Link_Name => "epoll_wait",
Convention => C;
end Epoll;

View File

@ -5,7 +5,7 @@ with Ada.Command_Line;
with Ada.Exceptions;
with Ada.Streams;
with Ada.Text_IO;
with Epoll;
with Async.Raw.Epoll;
with Interfaces.C;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
@ -19,13 +19,15 @@ with Mozzoni.Dispatch; use Mozzoni.Dispatch;
procedure Main is
use Async.Raw.Epoll;
use type Interfaces.Unsigned_32;
Server_Sock : Socket_Type;
Server_Addr : Sock_Addr_Type;
EpollFD : Epoll.Epoll_Fd_Type;
Server_Event : aliased Epoll.Event_Type;
Events : Epoll.Event_Array_Type (1 .. 32);
EpollFD : Epoll_Fd_Type;
Server_Event : aliased Event_Type;
Events : Event_Array_Type (1 .. 32);
Return_Value, Descriptors : Integer;
Socket_Request : Request_Type := (Non_Blocking_IO, True);
Should_Exit : Boolean := False;
@ -56,10 +58,10 @@ procedure Main is
end loop;
end Standard_Input;
procedure Add_To_Epoll (efd : Epoll.Epoll_Fd_Type;
procedure Add_To_Epoll (efd : Epoll_Fd_Type;
Client_Socket : in Socket_Type) is
Event : aliased Epoll.Event_Type;
Event : aliased Event_Type;
Call_Status : Integer;
Socket : constant Integer := To_C (Client_Socket);
@ -67,11 +69,11 @@ procedure Main is
begin
Event.Events := Epoll.EPOLLIN or Epoll.EPOLLRDHUP;
Event.Events := EPOLLIN or EPOLLRDHUP;
Event.Data.FD := Socket;
Call_Status := Epoll.Control (efd,
Epoll.Epoll_Ctl_Add,
Call_Status := Control (efd,
Epoll_Ctl_Add,
Socket,
Event'Access);
@ -97,17 +99,17 @@ begin
Listen_Socket (Server_Sock);
-- Since Linux 2.6.8, the size argument is ignored, but must be greater than zero;
EpollFD := Epoll.Create (1);
EpollFD := Create (1);
if EpollFD = -1 then
Log.Error ("Failed to create epoll(7) file descriptor");
return;
end if;
Server_Event.Events := Epoll.EPOLLIN or Epoll.EPOLLRDHUP;
Server_Event.Events := EPOLLIN or EPOLLRDHUP;
Server_Event.Data.FD := To_C (Server_Sock);
Return_Value := Epoll.Control (EpollFD, Epoll.Epoll_Ctl_Add, To_C (Server_Sock), Server_Event'Access);
Return_Value := Control (EpollFD, Epoll_Ctl_Add, To_C (Server_Sock), Server_Event'Access);
Log.Info ("mozzoni-daemon online and ready for work..");
Log.Debug ("Epoll descriptor: {1}", (1 => Log.d (EpollFD)));
@ -119,7 +121,7 @@ begin
end if;
Descriptors := 0;
Descriptors := Epoll.Wait (EpollFD,
Descriptors := Wait (EpollFD,
Events,
Events'Length,
100);
@ -127,10 +129,10 @@ begin
for Index in 1 .. Descriptors loop
declare
Polled_Event : Epoll.Event_Type := Events (Integer (Index));
Polled_Event : Event_Type := Events (Integer (Index));
Disconnecting : constant Boolean :=
(Polled_Event.Events and (Epoll.EPOLLHUP or Epoll.EPOLLRDHUP)) > 0;
(Polled_Event.Events and (EPOLLHUP or EPOLLRDHUP)) > 0;
Client_Socket : Socket_Type;
begin
@ -144,7 +146,7 @@ begin
Mozzoni.Client.Register_Client (Client_Socket);
Log.Debug ("Accepting a connection on fd {1}", (1 => Log.d (To_C (Client_Socket))));
elsif (Polled_Event.Events and Epoll.EPOLLIN) > 0 then
elsif (Polled_Event.Events and EPOLLIN) > 0 then
declare
S : constant Socket_Type := To_Ada (Polled_Event.Data.FD);
@ -164,8 +166,8 @@ begin
end;
elsif Disconnecting then
Return_Value := Epoll.Control (EpollFD,
Epoll.Epoll_Ctl_Del,
Return_Value := Control (EpollFD,
Epoll_Ctl_Del,
Polled_Event.Data.FD,
null);