Properly receive connections for epollecho, still WIP
Not currently handling EAGAIN on the socket we're reading data from
This commit is contained in:
parent
6f7d8d3cd0
commit
1836864f53
|
@ -49,9 +49,8 @@ package Epoll is
|
|||
end record;
|
||||
pragma Convention (C_Pass_By_Copy, Event_Type);
|
||||
|
||||
type Event_Array_Type is array (Positive range <>) of aliased Event_Type;
|
||||
type Event_Array_Type is array (Integer range <>) of aliased Event_Type;
|
||||
pragma Convention (C, Event_Array_Type);
|
||||
--for Event_Array_Type'Component_Size use Event_Type'Size;
|
||||
|
||||
|
||||
function Create (Size : Interfaces.C.int) return Epoll_Fd_Type;
|
||||
|
|
|
@ -9,8 +9,7 @@ with Epoll;
|
|||
|
||||
procedure Main is
|
||||
Event : aliased Epoll.Event_Type;
|
||||
Events : Epoll.Event_Array_Type;
|
||||
First_Event : aliased Epoll.Event_Type := Events (Events'First);
|
||||
Events : Epoll.Event_Array_Type (1 .. 10);
|
||||
|
||||
ServerSock : GNAT.Sockets.Socket_Type;
|
||||
ServerAddr : GNAT.Sockets.Sock_Addr_Type;
|
||||
|
@ -36,6 +35,10 @@ procedure Main is
|
|||
begin
|
||||
while true loop
|
||||
Ada.Streams.Read (Channel.All, Data, Offset);
|
||||
if Offset < 0 then
|
||||
Put_Line ("Wat!");
|
||||
end if;
|
||||
|
||||
exit when Offset = 0;
|
||||
Put (Character'Val (Data (1)));
|
||||
end loop;
|
||||
|
@ -43,6 +46,21 @@ procedure Main is
|
|||
GNAT.Sockets.Close_Socket (S);
|
||||
end Read_Data;
|
||||
|
||||
procedure Make_Non_Blocking (S : in GNAT.Sockets.Socket_Type) is
|
||||
Socket_Request : GNAT.Sockets.Request_Type :=
|
||||
GNAT.Sockets.Request_Type'(Name => Non_Blocking_IO,
|
||||
Enabled => True);
|
||||
begin
|
||||
Control_Socket (Socket => S,
|
||||
Request => Socket_Request);
|
||||
end Make_Non_Blocking;
|
||||
|
||||
procedure Error_Exit (Message : In String) is
|
||||
begin
|
||||
Ada.Text_IO.Put_Line (Message);
|
||||
Ada.Command_Line.Set_Exit_Status (1);
|
||||
end Error_Exit;
|
||||
|
||||
begin
|
||||
Put_Line ("Starting epoll-based echo server...");
|
||||
ServerAddr.Addr := Inet_Addr (Listen_Addr);
|
||||
|
@ -50,16 +68,16 @@ begin
|
|||
Create_Socket (ServerSock);
|
||||
Set_Socket_Option (ServerSock, Socket_Level, (Reuse_Address, True));
|
||||
Bind_Socket (ServerSock, ServerAddr);
|
||||
Make_Non_Blocking (ServerSock);
|
||||
Put_Line (".. bound to socket");
|
||||
|
||||
Listen_Socket (ServerSock);
|
||||
Put_Line (".. listening for connections");
|
||||
Put_Line (".. listening for connections on" & Image (ServerSock));
|
||||
|
||||
EpollFD := Epoll.Create (Events'Last);
|
||||
EpollFD := Epoll.Create (Events'Last + 1);
|
||||
|
||||
if EpollFD = -1 then
|
||||
Put_Line ("Failed to create epoll(7) file descriptor");
|
||||
Ada.Command_Line.Set_Exit_Status (1);
|
||||
Error_Exit ("Failed to create epoll(7) file descriptor");
|
||||
return;
|
||||
end if;
|
||||
|
||||
|
@ -69,38 +87,34 @@ begin
|
|||
Retval := Epoll.Control (EpollFD, Epoll.Epoll_Ctl_Add, To_C (ServerSock), Event'Access);
|
||||
|
||||
if Retval = -1 then
|
||||
Put_Line ("Epoll.Control call failed, not sure why");
|
||||
Ada.Command_Line.Set_Exit_Status (1);
|
||||
Error_Exit ("Epoll.Control call failed, not sure why");
|
||||
return;
|
||||
end if;
|
||||
|
||||
loop
|
||||
Put_Line ("Waiting..");
|
||||
Num_FDs := Epoll.Wait (EpollFD, First_Event'Access, 10, -1);
|
||||
-- Reset the Num_FDs before we wait again
|
||||
Num_FDs := 0;
|
||||
Num_FDs := Epoll.Wait (EpollFD, Events (Events'First)'Access, 10, -1);
|
||||
Put_Line ("Activity on" & Num_FDs'Img & " sockets");
|
||||
|
||||
if Num_FDs = -1 then
|
||||
Put_Line ("Failure on Epoll.Wait, exiting");
|
||||
Ada.Command_Line.Set_Exit_Status (1);
|
||||
Error_Exit ("Failure on Epoll.Wait, exiting");
|
||||
return;
|
||||
end if;
|
||||
|
||||
for I in 0 .. Num_FDs loop
|
||||
Put_Line ("Activity on" & Num_FDs'Img & " sockets");
|
||||
for I in 1 .. Num_FDs loop
|
||||
declare
|
||||
Index : constant Integer := Integer (I);
|
||||
Polled_Event : Epoll.Event_Type := Events (Index);
|
||||
ClientSock : GNAT.Sockets.Socket_Type;
|
||||
Socket_Request : GNAT.Sockets.Request_Type :=
|
||||
GNAT.Sockets.Request_Type'(Name => Non_Blocking_IO,
|
||||
Enabled => True);
|
||||
begin
|
||||
Put_Line ("Socket with activity" & Image (Polled_Event.Data.FD));
|
||||
Put_Line ("Socket (" & Index'Img & ") with data:" & Image (Polled_Event.Data.FD));
|
||||
|
||||
if Polled_Event.Data.FD = ServerSock then
|
||||
Put_Line ("Polled_Event is new connection, let's accept");
|
||||
Accept_Socket (ServerSock, ClientSock, ServerAddr);
|
||||
|
||||
Control_Socket (Socket => ClientSock,
|
||||
Request => Socket_Request);
|
||||
Make_Non_Blocking (ClientSock);
|
||||
|
||||
Event.Events := Epoll.Epoll_In_And_Et;
|
||||
Event.Data.FD := ClientSock;
|
||||
|
@ -112,15 +126,11 @@ begin
|
|||
To_C (ClientSock),
|
||||
Event'Access);
|
||||
if Retval = -1 then
|
||||
Put_Line ("Failed to add accepted socket to epollfd");
|
||||
Ada.Command_Line.Set_Exit_Status (1);
|
||||
Error_Exit ("Failed to add accepted socket to epollfd");
|
||||
return;
|
||||
end if;
|
||||
else
|
||||
Put ("Received data on socket: ");
|
||||
Put (Image (Polled_Event.Data.FD));
|
||||
Put (To_C (Polled_Event.Data.FD)'Img);
|
||||
New_Line;
|
||||
Put_Line ("Received data on socket: " & Image (Polled_Event.Data.FD));
|
||||
Read_Data (Polled_Event.Data.FD);
|
||||
end if;
|
||||
end;
|
||||
|
|
Loading…
Reference in New Issue