Skip to content
This repository was archived by the owner on May 22, 2023. It is now read-only.

Commit ae9fabf

Browse files
committedMay 20, 2020
let broker create all file descriptors
ref #134
1 parent 59e8498 commit ae9fabf

19 files changed

+205
-133
lines changed
 

‎init/gneiss-broker.adb

+29-23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
with Basalt.Strings;
33
with Gneiss.Config;
44
with Gneiss.Protocol;
5+
with Gneiss.Resource;
56
with Gneiss_Access;
67
with Gneiss_Log;
78
with SXML;
@@ -96,7 +97,7 @@ is
9697
In_Out => (Policy,
9798
Efd,
9899
Gneiss_Epoll.Linux,
99-
Gneiss.Syscall.Linux,
100+
Gneiss_Syscall.Linux,
100101
Main.Component_State,
101102
Load_File_Name,
102103
Gneiss.Linker.Linux));
@@ -112,7 +113,7 @@ is
112113
Global => (Input => Document,
113114
In_Out => (Policy,
114115
Efd,
115-
Gneiss.Syscall.Linux,
116+
Gneiss_Syscall.Linux,
116117
Main.Component_State,
117118
Gneiss.Linker.Linux,
118119
Gneiss_Epoll.Linux),
@@ -131,7 +132,7 @@ is
131132
Load_Message_Name,
132133
Load_Message_Label,
133134
Gneiss_Epoll.Linux,
134-
Gneiss.Syscall.Linux,
135+
Gneiss_Syscall.Linux,
135136
Proto.Linux,
136137
Read_Buffer.Ptr));
137138

@@ -145,7 +146,7 @@ is
145146
and then Valid_Read_Buffer,
146147
Global => (Input => (Document,
147148
Policy),
148-
In_Out => (Gneiss.Syscall.Linux,
149+
In_Out => (Gneiss_Syscall.Linux,
149150
Proto.Linux,
150151
Read_Buffer.Ptr,
151152
Load_Message_Name,
@@ -170,7 +171,7 @@ is
170171
Policy),
171172
In_Out => (Load_Message_Name,
172173
Load_Message_Label,
173-
Gneiss.Syscall.Linux,
174+
Gneiss_Syscall.Linux,
174175
Proto.Linux),
175176
Proof_In => Efd);
176177

@@ -187,7 +188,7 @@ is
187188
and then Initialized,
188189
Global => (Input => (Document,
189190
Policy),
190-
In_Out => (Gneiss.Syscall.Linux,
191+
In_Out => (Gneiss_Syscall.Linux,
191192
Proto.Linux),
192193
Proof_In => Efd);
193194

@@ -202,7 +203,7 @@ is
202203
and then Initialized,
203204
Global => (Input => (Document,
204205
Policy),
205-
In_Out => (Gneiss.Syscall.Linux,
206+
In_Out => (Gneiss_Syscall.Linux,
206207
Proto.Linux),
207208
Proof_In => Efd);
208209

@@ -218,7 +219,7 @@ is
218219
and then Initialized,
219220
Global => (Input => (Document,
220221
Policy),
221-
In_Out => (Gneiss.Syscall.Linux,
222+
In_Out => (Gneiss_Syscall.Linux,
222223
Proto.Linux),
223224
Proof_In => Efd);
224225

@@ -233,7 +234,7 @@ is
233234
and then Initialized,
234235
Global => (Input => (Document,
235236
Policy),
236-
In_Out => (Gneiss.Syscall.Linux,
237+
In_Out => (Gneiss_Syscall.Linux,
237238
Proto.Linux),
238239
Proof_In => Efd);
239240

@@ -385,10 +386,10 @@ is
385386
exit when SXML.Query.State_Result (State) /= SXML.Result_OK;
386387
SXML.Query.Attribute (State, Document, "name", Result, XML_Buf, Last);
387388
if Result = SXML.Result_OK then
388-
Gneiss.Syscall.Socketpair (Policy (Index).Fd, Fd);
389+
Gneiss_Syscall.Socketpair (Policy (Index).Fd, Fd);
389390
if Policy (Index).Fd > -1 then
390391
Gneiss_Epoll.Add (Efd, Policy (Index).Fd, Index, Success);
391-
Gneiss.Syscall.Fork (Pid);
392+
Gneiss_Syscall.Fork (Pid);
392393
if Pid < 0 then
393394
Gneiss_Log.Error ("Fork failed");
394395
Policy (Index).Fd := -1;
@@ -397,7 +398,7 @@ is
397398
Policy (Index).Pid := Pid;
398399
Policy (Index).Node := State;
399400
pragma Warnings (Off, "unused assignment to ""Fd""");
400-
Gneiss.Syscall.Close (Fd);
401+
Gneiss_Syscall.Close (Fd);
401402
pragma Warnings (On, "unused assignment to ""Fd""");
402403
Parent := True;
403404
Gneiss_Log.Info ("Started " & XML_Buf (XML_Buf'First .. Last)
@@ -425,11 +426,11 @@ is
425426
Last : Natural;
426427
begin
427428
Ret := 1;
428-
Gneiss.Syscall.Close (Integer (Efd));
429+
Gneiss_Syscall.Close (Integer (Efd));
429430
for I in Policy'Range loop
430431
pragma Loop_Invariant (Is_Valid);
431432
Policy (I).Node := SXML.Query.Invalid_State;
432-
Gneiss.Syscall.Close (Policy (I).Fd);
433+
Gneiss_Syscall.Close (Policy (I).Fd);
433434
end loop;
434435
SXML.Query.Attribute (Comp, Document, "file", Result, Load_File_Name, Last);
435436
if Result /= SXML.Result_OK and then Last not in Load_File_Name'Range then
@@ -460,7 +461,7 @@ is
460461
Read_Message (Index);
461462
end if;
462463
if Ev.Epoll_Hup or else Ev.Epoll_Rdhup then
463-
Gneiss.Syscall.Waitpid (Policy (Index).Pid, Success);
464+
Gneiss_Syscall.Waitpid (Policy (Index).Pid, Success);
464465
if Result = SXML.Result_OK then
465466
Gneiss_Log.Info ("Component "
466467
& XML_Buf (XML_Buf'First .. Last)
@@ -473,7 +474,7 @@ is
473474
& Basalt.Strings.Image (Success));
474475
end if;
475476
Gneiss_Epoll.Remove (Efd, Policy (Index).Fd, Success);
476-
Gneiss.Syscall.Close (Policy (Index).Fd);
477+
Gneiss_Syscall.Close (Policy (Index).Fd);
477478
Policy (Index).Node := SXML.Query.Init (Document);
478479
Policy (Index).Pid := -1;
479480
end if;
@@ -488,20 +489,22 @@ is
488489
Truncated : Boolean;
489490
Context : RFLX.Session.Packet.Context := RFLX.Session.Packet.Create;
490491
Last : RFLX.Types.Index;
492+
Fds : Gneiss_Syscall.Fd_Array (1 .. 1);
491493
Fd : Integer;
492494
begin
493-
Gneiss.Main.Peek_Message (Policy (Index).Fd, Read_Buffer.Ptr.all, Last, Truncated, Fd);
494-
Gneiss.Syscall.Drop_Message (Policy (Index).Fd);
495+
Gneiss.Main.Peek_Message (Policy (Index).Fd, Read_Buffer.Ptr.all, Last, Truncated, Fds);
496+
Fd := Fds (Fds'First);
497+
Gneiss_Syscall.Drop_Message (Policy (Index).Fd);
495498
if Last < Read_Buffer.Ptr.all'First then
496499
pragma Warnings (Off, "unused assignment to ""Fd""");
497-
Gneiss.Syscall.Close (Fd);
500+
Gneiss_Syscall.Close (Fd);
498501
pragma Warnings (On, "unused assignment to ""Fd""");
499502
Gneiss_Log.Warning ("Message too short, dropping");
500503
return;
501504
end if;
502505
if Truncated or else Last > Read_Buffer.Ptr.all'Last then
503506
pragma Warnings (Off, "unused assignment to ""Fd""");
504-
Gneiss.Syscall.Close (Fd);
507+
Gneiss_Syscall.Close (Fd);
505508
pragma Warnings (On, "unused assignment to ""Fd""");
506509
Gneiss_Log.Warning ("Message too large, dropping");
507510
return;
@@ -524,7 +527,7 @@ is
524527
else
525528
Gneiss_Log.Warning ("Invalid message, dropping");
526529
pragma Warnings (Off, "unused assignment to ""Fd""");
527-
Gneiss.Syscall.Close (Fd);
530+
Gneiss_Syscall.Close (Fd);
528531
pragma Warnings (On, "unused assignment to ""Fd""");
529532
end if;
530533
pragma Warnings (Off, "unused assignment to ""Context""");
@@ -740,13 +743,16 @@ is
740743
Name : String;
741744
Label : String)
742745
is
746+
Fds : Gneiss_Syscall.Fd_Array (1 .. 4);
743747
begin
748+
Resource.Allocate_Fd (Kind, Fds);
744749
Proto.Send_Message (Destination,
745750
Proto.Message'(Length => RFLX.Session.Length_Type (Name'Length + Label'Length),
746751
Action => RFLX.Session.Request,
747752
Kind => Kind,
748753
Name_Length => RFLX.Session.Length_Type (Name'Length),
749-
Payload => Convert_Message (Name & Label)));
754+
Payload => Convert_Message (Name & Label)),
755+
Resource.Truncate (Kind, Fds));
750756
end Send_Request;
751757

752758
procedure Send_Confirm (Destination : Integer;
@@ -761,7 +767,7 @@ is
761767
Kind => Kind,
762768
Name_Length => 0,
763769
Payload => Convert_Message (Label)),
764-
Filedesc);
770+
Gneiss_Syscall.Fd_Array'(0 => Filedesc));
765771
end Send_Confirm;
766772

767773
procedure Send_Reject (Destination : Integer;

‎init/gneiss-broker.ads

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
with SXML.Parser;
33
with Gneiss_Epoll;
44
with Gneiss.Linker;
5-
with Gneiss.Syscall;
5+
with Gneiss_Syscall;
66
with Gneiss.Main;
77

88
package Gneiss.Broker with
@@ -20,7 +20,7 @@ is
2020
Global => (In_Out => (Policy_State,
2121
Gneiss.Main.Component_State,
2222
Gneiss.Linker.Linux,
23-
Gneiss.Syscall.Linux,
23+
Gneiss_Syscall.Linux,
2424
Gneiss_Epoll.Linux,
2525
SXML.Parser.State));
2626

‎init/gneiss-main.adb

+35-31
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ is
3333
type Initializer_Service_Registry is array (RFLX.Session.Kind_Type'Range) of Initializer_Registry (1 .. 10);
3434
type RFLX_String is array (RFLX.Session.Length_Type range <>) of Character;
3535
type Request_Cache is record
36-
Name : String (1 .. 255) := (others => Character'First);
37-
Label : String (1 .. 255) := (others => Character'First);
38-
N_Last : Natural := 0;
39-
L_Last : Natural := 0;
36+
Name : String (1 .. 255) := (others => Character'First);
37+
Label : String (1 .. 255) := (others => Character'First);
38+
N_Last : Natural := 0;
39+
L_Last : Natural := 0;
40+
Fds : Gneiss_Syscall.Fd_Array (1 .. 2) := (others => -1);
4041
end record;
4142
type Dummy_Session is limited null record;
4243
package Queue is new Basalt.Queue (Request_Cache);
@@ -103,12 +104,12 @@ is
103104
Initializers,
104105
Requests,
105106
Read_Name,
106-
Gneiss.Syscall.Linux)),
107+
Gneiss_Syscall.Linux)),
107108
Pre => Read_Buffer.Ptr /= null,
108109
Post => Read_Buffer.Ptr /= null;
109110
function Broker_Event_Cap is new Gneiss_Platform.Create_Event_Cap (Dummy_Session, Broker_Event);
110111
procedure Handle_Answer (Kind : RFLX.Session.Kind_Type;
111-
Fd : Integer;
112+
Fd : Gneiss_Syscall.Fd_Array;
112113
Label : String) with
113114
Global => (In_Out => Initializers);
114115
procedure Load_Message (Context : RFLX.Session.Packet.Context;
@@ -278,7 +279,7 @@ is
278279
Truncated : Boolean;
279280
Context : RFLX.Session.Packet.Context := RFLX.Session.Packet.Create;
280281
Last : RFLX.Types.Index;
281-
Fd : Integer;
282+
Fd : Gneiss_Syscall.Fd_Array (1 .. 2);
282283
Name_Last : Natural;
283284
Label_Last : Natural;
284285
Kind : RFLX.Session.Kind_Type;
@@ -288,21 +289,26 @@ is
288289
procedure Load_Entry (E : out Request_Cache)
289290
is
290291
begin
292+
E.Fds := Fd;
291293
Load_Message (Context, E.Label, E.L_Last, E.Name, E.N_Last);
292294
end Load_Entry;
293295
begin
294296
Peek_Message (Broker_Fd, Read_Buffer.Ptr.all, Last, Truncated, Fd);
295-
Gneiss.Syscall.Drop_Message (Broker_Fd);
297+
Gneiss_Syscall.Drop_Message (Broker_Fd);
296298
if Last < Read_Buffer.Ptr.all'First then
297299
pragma Warnings (Off, "unused assignment to ""Fd""");
298-
Gneiss.Syscall.Close (Fd);
300+
for Filedesc of Fd loop
301+
Gneiss_Syscall.Close (Filedesc);
302+
end loop;
299303
pragma Warnings (On, "unused assignment to ""Fd""");
300304
Gneiss_Log.Warning ("Message too short, dropping");
301305
return;
302306
end if;
303307
if Truncated or else Last > Read_Buffer.Ptr.all'Last then
304308
pragma Warnings (Off, "unused assignment to ""Fd""");
305-
Gneiss.Syscall.Close (Fd);
309+
for Filedesc of Fd loop
310+
Gneiss_Syscall.Close (Filedesc);
311+
end loop;
306312
pragma Warnings (On, "unused assignment to ""Fd""");
307313
Gneiss_Log.Warning ("Message too large, dropping");
308314
return;
@@ -325,18 +331,15 @@ is
325331
then
326332
Kind := RFLX.Session.Packet.Get_Kind (Context);
327333
case RFLX.Session.Packet.Get_Action (Context) is
328-
when RFLX.Session.Request =>
329-
if Queue.Count (Requests (Kind)) >= Queue.Size (Requests (Kind)) then
330-
Reject_Request (Kind);
331-
end if;
332-
Put (Requests (Kind));
333-
pragma Assert (RFLX.Session.Packet.Has_Buffer (Context));
334-
when RFLX.Session.Confirm =>
335-
Load_Message (Context, Read_Label, Label_Last, Read_Name, Name_Last);
336-
Handle_Answer (Kind, Fd, Read_Label (Read_Label'First .. Label_Last));
337-
when RFLX.Session.Reject =>
338-
Load_Message (Context, Read_Label, Label_Last, Read_Name, Name_Last);
339-
Handle_Answer (Kind, Fd, Read_Label (Read_Label'First .. Label_Last));
334+
when RFLX.Session.Request =>
335+
if Queue.Count (Requests (Kind)) >= Queue.Size (Requests (Kind)) then
336+
Reject_Request (Kind);
337+
end if;
338+
Put (Requests (Kind));
339+
pragma Assert (RFLX.Session.Packet.Has_Buffer (Context));
340+
when RFLX.Session.Confirm | RFLX.Session.Reject =>
341+
Load_Message (Context, Read_Label, Label_Last, Read_Name, Name_Last);
342+
Handle_Answer (Kind, Fd, Read_Label (Read_Label'First .. Label_Last));
340343
end case;
341344
end if;
342345
pragma Assert (RFLX.Session.Packet.Has_Buffer (Context));
@@ -345,17 +348,17 @@ is
345348
end Broker_Event;
346349

347350
procedure Handle_Answer (Kind : RFLX.Session.Kind_Type;
348-
Fd : Integer;
351+
Fd : Gneiss_Syscall.Fd_Array;
349352
Label : String)
350353
is
351354
begin
352355
for I of Initializers (Kind) loop
353356
if Gneiss_Platform.Is_Valid (I) then
354357
case Kind is
355358
when RFLX.Session.Message =>
356-
Message_Initializer (I, Label, Fd >= 0, Fd);
359+
Message_Initializer (I, Label, Fd (Fd'First) >= 0, Fd (Fd'First));
357360
when RFLX.Session.Log =>
358-
Message_Initializer (I, Label, Fd >= 0, Fd);
361+
Message_Initializer (I, Label, Fd (Fd'First) >= 0, Fd (Fd'First));
359362
end case;
360363
Gneiss_Platform.Invalidate (I);
361364
end if;
@@ -369,16 +372,17 @@ is
369372
procedure Peek is new Queue.Generic_Peek (Peek);
370373
procedure Peek (E : Request_Cache)
371374
is
372-
Fd : Integer := -1;
375+
Fd : Gneiss_Syscall.Fd_Array (1 .. 2) := E.Fds;
373376
Name : RFLX_String (1 .. RFLX.Session.Length_Type (E.N_Last));
374377
Label : RFLX_String (1 .. RFLX.Session.Length_Type (E.L_Last));
375378
Index : Positive := E.Name'First;
379+
Num : Natural;
376380
begin
377381
Message_Dispatcher (Services (Kind),
378382
E.Name (E.Name'First .. E.N_Last),
379383
E.Label (E.Label'First .. E.L_Last),
380-
Fd);
381-
Accepted := Fd >= 0;
384+
Fd, Num);
385+
Accepted := Num > 0;
382386
if not Accepted then
383387
return;
384388
end if;
@@ -399,7 +403,7 @@ is
399403
Kind => Kind,
400404
Name_Length => RFLX.Session.Length_Type (E.N_Last),
401405
Payload => Name & Label),
402-
Fd);
406+
Fd (Fd'First .. Fd'First + Num - 1));
403407
end Peek;
404408
begin
405409
Peek (Requests (Kind));
@@ -530,14 +534,14 @@ is
530534
Message : out RFLX.Types.Bytes;
531535
Last : out RFLX.Types.Index;
532536
Truncated : out Boolean;
533-
Fd : out Integer) with
537+
Fd : out Gneiss_Syscall.Fd_Array) with
534538
SPARK_Mode => Off
535539
is
536540
use type RFLX.Types.Index;
537541
Trunc : Integer;
538542
Length : Integer;
539543
begin
540-
Gneiss.Syscall.Peek_Message (Socket, Message'Address, Message'Length, Fd, Length, Trunc);
544+
Gneiss_Syscall.Peek_Message (Socket, Message'Address, Message'Length, Fd, Fd'Length, Length, Trunc);
541545
Truncated := Trunc = 1;
542546
if Length < 1 then
543547
Last := RFLX.Types.Index'First;

‎init/gneiss-main.ads

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
with RFLX.Types;
3-
with Gneiss.Syscall;
3+
with Gneiss_Syscall;
44
with Gneiss_Epoll;
55
with Gneiss.Linker;
66

@@ -14,15 +14,15 @@ is
1414
Fd : Integer;
1515
Status : out Integer) with
1616
Global => (In_Out => (Component_State,
17-
Gneiss.Syscall.Linux,
17+
Gneiss_Syscall.Linux,
1818
Gneiss_Epoll.Linux,
1919
Gneiss.Linker.Linux));
2020

2121
procedure Peek_Message (Socket : Integer;
2222
Message : out RFLX.Types.Bytes;
2323
Last : out RFLX.Types.Index;
2424
Truncated : out Boolean;
25-
Fd : out Integer) with
26-
Global => (In_Out => Gneiss.Syscall.Linux);
25+
Fd : out Gneiss_Syscall.Fd_Array) with
26+
Global => (In_Out => Gneiss_Syscall.Linux);
2727

2828
end Gneiss.Main;

‎init/gneiss-resource.adb

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
package body Gneiss.Resource with
3+
SPARK_Mode
4+
is
5+
6+
procedure Allocate_Fd (Kind : RFLX.Session.Kind_Type;
7+
Fds : out Gneiss_Syscall.Fd_Array)
8+
is
9+
begin
10+
Fds := (others => -1);
11+
case Kind is
12+
when RFLX.Session.Message | RFLX.Session.Log =>
13+
Gneiss_Syscall.Socketpair (Fds (Fds'First), Fds (Fds'First + 1));
14+
end case;
15+
end Allocate_Fd;
16+
17+
function Truncate (Kind : RFLX.Session.Kind_Type;
18+
Fds : Gneiss_Syscall.Fd_Array) return Gneiss_Syscall.Fd_Array
19+
is
20+
begin
21+
case Kind is
22+
when RFLX.Session.Message | RFLX.Session.Log =>
23+
return Fds (Fds'First .. Fds'First + 1);
24+
end case;
25+
end Truncate;
26+
27+
end Gneiss.Resource;

‎init/gneiss-resource.ads

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
with Gneiss_Syscall;
3+
with RFLX.Session;
4+
5+
package Gneiss.Resource with
6+
SPARK_Mode
7+
is
8+
9+
procedure Allocate_Fd (Kind : RFLX.Session.Kind_Type;
10+
Fds : out Gneiss_Syscall.Fd_Array) with
11+
Pre => Fds'Length >= 2;
12+
13+
function Truncate (Kind : RFLX.Session.Kind_Type;
14+
Fds : Gneiss_Syscall.Fd_Array) return Gneiss_Syscall.Fd_Array;
15+
16+
end Gneiss.Resource;

‎src/log/server/linux/gneiss-log-dispatcher.adb

+18-16
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ with RFLX.Session;
33
with System;
44
with Gneiss_Epoll;
55
with Gneiss_Platform;
6-
with Gneiss.Syscall;
6+
with Gneiss_Syscall;
77
with Gneiss_Internal.Message;
88

99
package body Gneiss.Log.Dispatcher with
@@ -15,7 +15,8 @@ is
1515
procedure Dispatch_Event (Session : in out Dispatcher_Session;
1616
Name : String;
1717
Label : String;
18-
Fd : in out Integer);
18+
Fd : in out Gneiss_Syscall.Fd_Array;
19+
Num : out Natural);
1920

2021
procedure Session_Event (Session : in out Server_Session);
2122

@@ -38,17 +39,22 @@ is
3839
procedure Dispatch_Event (Session : in out Dispatcher_Session;
3940
Name : String;
4041
Label : String;
41-
Fd : in out Integer)
42+
Fd : in out Gneiss_Syscall.Fd_Array;
43+
Num : out Natural)
4244
is
4345
begin
4446
Session.Client_Fd := -1;
4547
Session.Accepted := False;
46-
if Fd >= 0 then
47-
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => Fd), "", "");
48+
if Fd'Length = 1 then
49+
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => Fd (Fd'First), others => -1), "", "");
50+
Num := 0;
4851
return;
4952
end if;
50-
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => -1), Name, Label);
51-
Fd := (if Session.Accepted then Session.Client_Fd else -1);
53+
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => -1,
54+
Client_Fd => Fd (Fd'First),
55+
Server_Fd => Fd (Fd'First + 1)),
56+
Name, Label);
57+
Num := (if Session.Accepted then 1 else 0);
5258
end Dispatch_Event;
5359

5460
procedure Initialize (Session : in out Dispatcher_Session;
@@ -83,18 +89,14 @@ is
8389
Server_S : in out Server_Session;
8490
Idx : Session_Index := 1)
8591
is
86-
pragma Unreferenced (Cap);
92+
pragma Unreferenced (Session);
8793
begin
88-
Gneiss.Syscall.Socketpair (Session.Client_Fd, Server_S.Fd);
89-
if Session.Client_Fd < 0 or else Server_S.Fd < 0 then
90-
return;
91-
end if;
94+
Server_S.Fd := Cap.Server_Fd;
9295
Server_S.Index := Gneiss.Session_Index_Option'(Valid => True, Value => Idx);
9396
Server_S.E_Cap := Event_Cap (Server_S);
9497
Server_Instance.Initialize (Server_S);
9598
if not Server_Instance.Ready (Server_S) then
96-
Gneiss.Syscall.Close (Server_S.Fd);
97-
Gneiss.Syscall.Close (Session.Client_Fd);
99+
Gneiss_Syscall.Close (Server_S.Fd);
98100
Server_S.Index := Gneiss.Session_Index_Option'(Valid => False);
99101
end if;
100102
end Session_Initialize;
@@ -103,9 +105,9 @@ is
103105
Cap : Dispatcher_Capability;
104106
Server_S : in out Server_Session)
105107
is
106-
pragma Unreferenced (Cap);
107108
Ignore_Success : Integer;
108109
begin
110+
Session.Client_Fd := Cap.Client_Fd;
109111
Gneiss_Epoll.Add (Session.Epoll_Fd, Server_S.Fd, Event_Cap_Address (Server_S), Ignore_Success);
110112
Session.Accepted := True;
111113
end Session_Accept;
@@ -121,7 +123,7 @@ is
121123
and then Server_S.Fd = Cap.Clean_Fd
122124
then
123125
Gneiss_Epoll.Remove (Session.Epoll_Fd, Server_S.Fd, Ignore_Success);
124-
Gneiss.Syscall.Close (Server_S.Fd);
126+
Gneiss_Syscall.Close (Server_S.Fd);
125127
Server_Instance.Finalize (Server_S);
126128
Gneiss_Platform.Invalidate (Server_S.E_Cap);
127129
Server_S.Index := Gneiss.Session_Index_Option'(Valid => False);

‎src/message/client/linux/gneiss-message-generic_client.adb

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
with System;
33
with Gneiss.Protocol;
4-
with Gneiss.Syscall;
4+
with Gneiss_Syscall;
55
with Gneiss_Epoll;
66
with Gneiss_Platform;
77
with Gneiss_Internal.Message;
@@ -128,7 +128,7 @@ is
128128
Ignore_Success : Integer;
129129
begin
130130
Gneiss_Epoll.Remove (Session.Epoll_Fd, Session.File_Descriptor, Ignore_Success);
131-
Gneiss.Syscall.Close (Session.File_Descriptor);
131+
Gneiss_Syscall.Close (Session.File_Descriptor);
132132
Session.Label.Last := 0;
133133
Session.Index := Gneiss.Session_Index_Option'(Valid => False);
134134
end Finalize;

‎src/message/linux/gneiss_internal-message.ads

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ is
3333
end record;
3434

3535
type Dispatcher_Capability is limited record
36-
Clean_Fd : Integer := -1;
36+
Clean_Fd : Integer := -1;
37+
Client_Fd : Integer := -1;
38+
Server_Fd : Integer := -1;
3739
end record;
3840

3941
procedure Write (Fd : Integer;

‎src/message/server/linux/gneiss-message-dispatcher.adb

+19-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
with System;
33
with Gneiss_Epoll;
44
with Gneiss_Platform;
5-
with Gneiss.Syscall;
5+
with Gneiss_Syscall;
66
with RFLX.Session;
77

88
package body Gneiss.Message.Dispatcher with
@@ -23,7 +23,8 @@ is
2323
procedure Dispatch_Event (Session : in out Dispatcher_Session;
2424
Name : String;
2525
Label : String;
26-
Fd : in out Integer);
26+
Fd : in out Gneiss_Syscall.Fd_Array;
27+
Num : out Natural);
2728

2829
function Server_Event_Address (Session : Server_Session) return System.Address with
2930
SPARK_Mode => Off
@@ -35,17 +36,22 @@ is
3536
procedure Dispatch_Event (Session : in out Dispatcher_Session;
3637
Name : String;
3738
Label : String;
38-
Fd : in out Integer)
39+
Fd : in out Gneiss_Syscall.Fd_Array;
40+
Num : out Natural)
3941
is
4042
begin
4143
Session.Client_Fd := -1;
4244
Session.Accepted := False;
43-
if Fd >= 0 then
44-
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => Fd), "", "");
45+
if Fd'Length = 1 then
46+
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => Fd (Fd'First), others => -1), "", "");
47+
Num := 0;
4548
return;
4649
end if;
47-
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => -1), Name, Label);
48-
Fd := (if Session.Accepted then Session.Client_Fd else -1);
50+
Dispatch (Session, Dispatcher_Capability'(Clean_Fd => -1,
51+
Client_Fd => Fd (Fd'First),
52+
Server_Fd => Fd (Fd'First + 1)),
53+
Name, Label);
54+
Num := (if Session.Accepted then 1 else 0);
4955
end Dispatch_Event;
5056

5157
procedure Initialize (Session : in out Dispatcher_Session;
@@ -79,36 +85,32 @@ is
7985

8086
function Valid_Session_Request (Session : Dispatcher_Session;
8187
Cap : Dispatcher_Capability) return Boolean is
82-
(Cap.Clean_Fd < 0);
88+
(Cap.Client_Fd > -1 and then Cap.Server_Fd > -1);
8389

8490
procedure Session_Initialize (Session : in out Dispatcher_Session;
8591
Cap : Dispatcher_Capability;
8692
Server_S : in out Server_Session;
8793
Idx : Session_Index := 1)
8894
is
89-
pragma Unreferenced (Cap);
95+
pragma Unreferenced (Session);
9096
begin
91-
Gneiss.Syscall.Socketpair (Session.Client_Fd, Server_S.Fd);
92-
if Session.Client_Fd < 0 or else Server_S.Fd < 0 then
93-
return;
94-
end if;
97+
Server_S.Fd := Cap.Server_Fd;
9598
Server_S.Index := Gneiss.Session_Index_Option'(Valid => True, Value => Idx);
9699
Server_S.E_Cap := Event_Cap (Server_S);
97100
Server_Instance.Initialize (Server_S);
98101
if not Server_Instance.Ready (Server_S) then
99-
Gneiss.Syscall.Close (Server_S.Fd);
100-
Gneiss.Syscall.Close (Session.Client_Fd);
101102
Server_S.Index := Gneiss.Session_Index_Option'(Valid => False);
103+
Gneiss_Syscall.Close (Server_S.Fd);
102104
end if;
103105
end Session_Initialize;
104106

105107
procedure Session_Accept (Session : in out Dispatcher_Session;
106108
Cap : Dispatcher_Capability;
107109
Server_S : in out Server_Session)
108110
is
109-
pragma Unreferenced (Cap);
110111
Ignore_Success : Integer;
111112
begin
113+
Session.Client_Fd := Cap.Client_Fd;
112114
Gneiss_Epoll.Add (Session.Epoll_Fd, Server_S.Fd, Server_Event_Address (Server_S), Ignore_Success);
113115
Session.Accepted := True;
114116
end Session_Accept;
@@ -124,7 +126,7 @@ is
124126
and then Server_S.Fd = Cap.Clean_Fd
125127
then
126128
Gneiss_Epoll.Remove (Session.Epoll_Fd, Server_S.Fd, Ignore_Success);
127-
Gneiss.Syscall.Close (Server_S.Fd);
129+
Gneiss_Syscall.Close (Server_S.Fd);
128130
Server_Instance.Finalize (Server_S);
129131
Server_S.Index := Gneiss.Session_Index_Option'(Valid => False);
130132
end if;
+2-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11

2-
with Gneiss.Syscall;
3-
42
package body Gneiss.Protocol with
53
SPARK_Mode => Off
64
is
75

86
procedure Send_Message (Destination : Integer;
97
Data : Message;
10-
File_Desc : Integer := -1)
8+
File_Desc : Gneiss_Syscall.Fd_Array := Gneiss_Syscall.Fd_Array'(1 .. 0 => -1))
119
is
1210
begin
13-
Gneiss.Syscall.Write_Message (Destination, Data'Address, Data'Size / 8, File_Desc);
11+
Gneiss_Syscall.Write_Message (Destination, Data'Address, Data'Size / 8, File_Desc, File_Desc'Length);
1412
end Send_Message;
1513

1614
end Gneiss.Protocol;

‎src/platform/linux/gneiss-protocol.ads

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
with RFLX.Session;
3+
with Gneiss_Syscall;
34

45
generic
56
type Byte is (<>);
@@ -28,7 +29,7 @@ is
2829

2930
procedure Send_Message (Destination : Integer;
3031
Data : Message;
31-
File_Desc : Integer := -1) with
32+
File_Desc : Gneiss_Syscall.Fd_Array := Gneiss_Syscall.Fd_Array'(1 .. 0 => -1)) with
3233
Global => (In_Out => Linux);
3334

3435
function Image (V : RFLX.Session.Action_Type) return String is

‎src/platform/linux/gneiss-syscall.adb

-6
This file was deleted.

‎src/platform/linux/gneiss_log.adb

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
with Gneiss.Syscall;
2+
with Gneiss_Syscall;
33

44
package body Gneiss_Log with
55
SPARK_Mode
@@ -13,19 +13,19 @@ is
1313
procedure Info (S : String)
1414
is
1515
begin
16-
Gneiss.Syscall.Fputs ("I: " & S & Terminator);
16+
Gneiss_Syscall.Fputs ("I: " & S & Terminator);
1717
end Info;
1818

1919
procedure Warning (S : String)
2020
is
2121
begin
22-
Gneiss.Syscall.Fputs (Blue & "W: " & S & Reset & Terminator);
22+
Gneiss_Syscall.Fputs (Blue & "W: " & S & Reset & Terminator);
2323
end Warning;
2424

2525
procedure Error (S : String)
2626
is
2727
begin
28-
Gneiss.Syscall.Fputs (Red & "E: " & S & Reset & Terminator);
28+
Gneiss_Syscall.Fputs (Red & "E: " & S & Reset & Terminator);
2929
end Error;
3030

3131
end Gneiss_Log;

‎src/platform/linux/gneiss_platform.adb

+5-3
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,21 @@ is
156156
procedure Dispatcher_Call (Cap : Dispatcher_Cap;
157157
Name : String;
158158
Label : String;
159-
Fd : in out Integer)
159+
Fd : in out Gneiss_Syscall.Fd_Array;
160+
Num : out Natural)
160161
is
161162
procedure Dispatch (S : in out Session_Type;
162163
N : String;
163164
L : String;
164-
F : in out Integer) with
165+
F : in out Gneiss_Syscall.Fd_Array;
166+
C : out Natural) with
165167
Import,
166168
Address => Cap.Address;
167169
Session : Session_Type with
168170
Import,
169171
Address => Cap.Cap;
170172
begin
171-
Dispatch (Session, Name, Label, Fd);
173+
Dispatch (Session, Name, Label, Fd, Num);
172174
end Dispatcher_Call;
173175

174176
end Gneiss_Platform;

‎src/platform/linux/gneiss_platform.ads

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
with RFLX.Session;
3+
with Gneiss_Syscall;
34
private with System;
45

56
package Gneiss_Platform with
@@ -94,7 +95,8 @@ is
9495
with procedure Dispatch (Session : in out Session_Type;
9596
Name : String;
9697
Label : String;
97-
Fd : in out Integer);
98+
Fd : in out Gneiss_Syscall.Fd_Array;
99+
Num : out Natural);
98100
function Create_Dispatcher_Cap (S : Session_Type) return Dispatcher_Cap with
99101
Post => Is_Valid (Create_Dispatcher_Cap'Result);
100102

@@ -103,7 +105,8 @@ is
103105
procedure Dispatcher_Call (Cap : Dispatcher_Cap;
104106
Name : String;
105107
Label : String;
106-
Fd : in out Integer) with
108+
Fd : in out Gneiss_Syscall.Fd_Array;
109+
Num : out Natural) with
107110
Pre => Is_Valid (Cap);
108111

109112
private

‎src/platform/linux/gneiss_syscall.adb

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
package body Gneiss_Syscall with
3+
SPARK_Mode => Off
4+
is
5+
6+
end Gneiss_Syscall;

‎src/platform/linux/gneiss-syscall.ads ‎src/platform/linux/gneiss_syscall.ads

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11

22
with System;
33

4-
package Gneiss.Syscall with
4+
package Gneiss_Syscall with
55
SPARK_Mode,
66
Abstract_State => Linux,
77
Initializes => Linux,
88
Elaborate_Body
99
is
1010

11+
type Fd_Array is array (Natural range <>) of Integer;
12+
1113
procedure Socketpair (Fd1 : out Integer;
1214
Fd2 : out Integer) with
1315
Import,
@@ -45,7 +47,8 @@ is
4547
procedure Write_Message (Socket : Integer;
4648
Message : System.Address;
4749
Size : Integer;
48-
Fd : Integer := -1) with
50+
Fds : Fd_Array;
51+
Num : Natural) with
4952
Import,
5053
Convention => C,
5154
External_Name => "gneiss_write_message",
@@ -54,7 +57,8 @@ is
5457
procedure Peek_Message (Socket : Integer;
5558
Message : System.Address;
5659
Size : Integer;
57-
Fd : out Integer;
60+
Fds : out Fd_Array;
61+
Num : Natural;
5862
Length : out Integer;
5963
Trunc : out Integer) with
6064
Import,
@@ -80,4 +84,4 @@ is
8084
External_Name => "getpid",
8185
Global => (Input => Linux);
8286

83-
end Gneiss.Syscall;
87+
end Gneiss_Syscall;

‎src/platform/linux/syscall.c

+18-13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
//#define ENABLE_TRACE
1010
#include <trace.h>
1111

12+
#ifndef min
13+
#define min(a,b) (((a) < (b)) ? (a) : (b))
14+
#endif
15+
1216
void gneiss_socketpair(int *fd1, int *fd2)
1317
{
1418
int fds[2];
@@ -59,14 +63,14 @@ void gneiss_dup(int oldfd, int *newfd)
5963
}
6064
}
6165

62-
void gneiss_write_message(int sock, void *msg, size_t size, int fd)
66+
void gneiss_write_message(int sock, void *msg, size_t size, int *fd, int num)
6367
{
64-
TRACE("sock=%d msg=%p size=%zu\n", sock, msg, size);
68+
TRACE("sock=%d msg=%p size=%zu fd=%p num=%d\n", sock, msg, size, fd, num);
6569
struct msghdr message;
6670
struct iovec iov;
6771
union {
6872
struct cmsghdr cmsghdr;
69-
char control[CMSG_SPACE(sizeof(int))];
73+
char control[CMSG_SPACE(sizeof(int) * num)];
7074
} cmsgu;
7175
struct cmsghdr *cmsg;
7276

@@ -83,15 +87,15 @@ void gneiss_write_message(int sock, void *msg, size_t size, int fd)
8387
message.msg_iov = &iov;
8488
message.msg_iovlen = 1;
8589

86-
if(fd >= 0){
90+
if(num > 0){
8791
message.msg_control = cmsgu.control;
8892
message.msg_controllen = sizeof(cmsgu.control);
8993

9094
cmsg = CMSG_FIRSTHDR(&message);
91-
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
95+
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num);
9296
cmsg->cmsg_level = SOL_SOCKET;
9397
cmsg->cmsg_type = SCM_RIGHTS;
94-
*((int *)CMSG_DATA(cmsg)) = fd;
98+
memcpy(CMSG_DATA(cmsg), fd, sizeof(int) * num);
9599
}else{
96100
message.msg_control = 0;
97101
message.msg_controllen = 0;
@@ -101,15 +105,15 @@ void gneiss_write_message(int sock, void *msg, size_t size, int fd)
101105
}
102106
}
103107

104-
void gneiss_peek_message(int sock, void *msg, size_t size, int *fd, int *length, int *trunc)
108+
void gneiss_peek_message(int sock, void *msg, size_t size, int *fd, int num, int *length, int *trunc)
105109
{
106-
TRACE("sock=%d msg=%p size=%zu fd=%p length=%p trunc=%p\n", sock, msg, size, fd, length, trunc);
110+
TRACE("sock=%d msg=%p size=%zu fd=%p num=%d length=%p trunc=%p\n", sock, msg, size, fd, num, length, trunc);
107111
ssize_t ssize;
108112
struct msghdr message;
109113
struct iovec iov;
110114
union {
111115
struct cmsghdr cmsghdr;
112-
char control[CMSG_SPACE(sizeof(int))];
116+
char control[CMSG_SPACE(sizeof(int) * num)];
113117
} cmsgu;
114118
struct cmsghdr *cmsg;
115119

@@ -122,7 +126,9 @@ void gneiss_peek_message(int sock, void *msg, size_t size, int *fd, int *length,
122126
message.msg_iovlen = 1;
123127
message.msg_control = cmsgu.control;
124128
message.msg_controllen = sizeof(cmsgu.control);
125-
*fd = -1;
129+
for(int i = 0; i < num; i++){
130+
fd[i] = -1;
131+
}
126132
*length = recvmsg(sock, &message, MSG_PEEK | MSG_TRUNC);
127133
if(*length < 0){
128134
perror("recvmsg");
@@ -136,10 +142,9 @@ void gneiss_peek_message(int sock, void *msg, size_t size, int *fd, int *length,
136142
TRACE_CONT("\n");
137143
*trunc = !!(message.msg_flags & MSG_TRUNC);
138144
cmsg = CMSG_FIRSTHDR(&message);
139-
if(cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))
140-
&& cmsg->cmsg_level == SOL_SOCKET
145+
if(cmsg && cmsg->cmsg_level == SOL_SOCKET
141146
&& cmsg->cmsg_type == SCM_RIGHTS){
142-
*fd = *((int *)CMSG_DATA(cmsg));
147+
memcpy(fd, CMSG_DATA(cmsg), min(sizeof(int) * num, cmsg->cmsg_len));
143148
}
144149
}
145150

0 commit comments

Comments
 (0)
This repository has been archived.