|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 21504 (0x5400)
Types: Ada Source
Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Transport_Stream, seg_0009de
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
└─⟦5a81ac88f⟧ »Space Info Vol 1«
└─⟦this⟧
with Machine; -- JMK 10/27/86
package body Transport_Stream is
Buffer_Size : constant := 2 ** 10;
subtype Data_Count is Natural range 0 .. Buffer_Size;
subtype Data_Index is Data_Count range 0 .. Data_Count'Last - 1;
type Buffer_Type is
record
First : Data_Index;
Count : Data_Count;
Data : Byte_Defs.Byte_String (Data_Index'First .. Data_Index'Last);
end record;
type Pool_Type (Network_Length : Natural;
Remote_Host_Length : Natural;
Remote_Socket_Length : Natural;
Local_Socket_Length : Natural) is
record
Next : Pool_List;
Idle : Stream_List;
Network :
Transport_Defs.Network_Name (1 .. Network_Length);
Remote_Host : Transport_Defs.Host_Id (1 .. Remote_Host_Length);
Remote_Socket : Transport_Defs.Socket_Id
(1 .. Remote_Socket_Length);
Local_Socket : Transport_Defs.Socket_Id
(1 .. Local_Socket_Length);
end record;
type Stream_Type is
record
Next : Stream_List := null;
Pool : Pool_Id := null;
Unique : Unique_Id := Null_Unique_Id;
User_Id : Integer := 0;
Referenced : Boolean := False;
Connection : Transport.Connection_Id;
Transmit, Receive : Buffer_Type;
end record;
function Is_Null (Stream : Stream_Id) return Boolean is
begin
return Stream.Stream = null or else
Stream.Unique /= Stream.Stream.Unique;
end Is_Null;
procedure Check_Non_Null (Stream : Stream_Id) is
begin
if Is_Null (Stream) then
raise Not_Connected;
end if;
end Check_Non_Null;
procedure Initialize (Buffer : out Buffer_Type) is
begin
Buffer.First := Buffer.Data'First;
Buffer.Count := 0;
end Initialize;
function Equals (X, Y : Transport_Defs.Network_Name) return Boolean is
begin
return Transport_Defs."="
(Transport_Defs.Normalize (X),
Transport_Defs.Normalize (Y));
end Equals;
function Equals (X, Y : Transport_Defs.Host_Id) return Boolean is
begin
return Transport_Defs."="
(Transport_Defs.Normalize (X),
Transport_Defs.Normalize (Y));
end Equals;
function Equals (X, Y : Transport_Defs.Socket_Id) return Boolean is
begin
return Transport_Defs."="
(Transport_Defs.Normalize (X),
Transport_Defs.Normalize (Y));
end Equals;
task Worker is
entry Create (Pool : out Pool_Id;
Network : Transport_Defs.Network_Name;
Remote_Host : Transport_Defs.Host_Id;
Remote_Socket : Transport_Defs.Socket_Id;
Local_Socket : Transport_Defs.Socket_Id);
entry Allocate (Stream : out Stream_Id);
entry Allocate (Stream : out Stream_Id;
Pool : Pool_Id);
entry Allocate (Stream : out Stream_Id;
Network : Transport_Defs.Network_Name;
Remote_Host : Transport_Defs.Host_Id;
Remote_Socket : Transport_Defs.Socket_Id);
entry Deallocate (Stream : Stream_Id);
entry Disconnect (Stream : Stream_Id);
entry Scavenge (Pool : Pool_Id := null);
entry Destroy (Pool : Pool_Id := null);
entry Finalize;
end Worker;
function Create (Network : Transport_Defs.Network_Name;
Remote_Host : Transport_Defs.Host_Id;
Remote_Socket : Transport_Defs.Socket_Id;
Local_Socket : Transport_Defs.Socket_Id :=
Transport_Defs.Null_Socket_Id)
return Pool_Id is
Pool : Pool_Id;
begin
Worker.Create
(Pool, Network, Remote_Host, Remote_Socket, Local_Socket);
return Pool;
end Create;
procedure Scavenge (Pool : Pool_Id) is
begin
Worker.Scavenge (Pool);
end Scavenge;
procedure Scavenge is
begin
Worker.Scavenge;
end Scavenge;
procedure Destroy (Pool : Pool_Id) is
begin
Worker.Destroy (Pool);
end Destroy;
task Scavenger is
entry Start;
entry Stop;
entry Finalize;
end Scavenger;
task body Scavenger is
Running : Boolean := True;
begin
loop
if Running then
select
accept Start do
Running := True;
end Start;
or
accept Stop do
Running := False;
end Stop;
or
accept Finalize;
exit;
or
delay 30.0;
Scavenge;
end select;
else
select
accept Start do
Running := True;
end Start;
or
accept Stop do
Running := False;
end Stop;
or
accept Finalize;
exit;
or
terminate;
end select;
end if;
end loop;
end Scavenger;
procedure Finalize is
begin
-- JMK 10/24/86 Not useful for shared elaboration.
null;
-- begin
-- Worker.Finalize;
-- exception
-- when Tasking_Error =>
-- null;
-- end;
-- begin
-- Scavenger.Finalize;
-- exception
-- when Tasking_Error =>
-- null;
-- end;
end Finalize;
procedure Allocate (Stream : out Stream_Id;
Connection : Transport.Connection_Id) is
The_Stream : Stream_Id;
begin
Worker.Allocate (The_Stream);
The_Stream.Stream.Connection := Connection;
Stream := The_Stream;
exception
when Tasking_Error =>
raise Not_Connected;
end Allocate;
procedure Check_Ok (Status : Transport_Defs.Status_Code) is
begin
case Status is
when Transport_Defs.Ok =>
null;
when others =>
raise Not_Connected;
end case;
end Check_Ok;
procedure Get_Connected (Stream : Stream_Id;
Is_New : out Boolean;
Network : Transport_Defs.Network_Name;
Host : Transport_Defs.Host_Id;
Socket : Transport_Defs.Socket_Id) is
Connection : Transport.Connection_Id
renames Stream.Stream.Connection;
Status : Transport_Defs.Status_Code;
Retries : constant Natural := 2; -- JMK 5/7/87
Backoff : constant Duration := 5.0; -- JMK 5/7/87
begin
Check_Non_Null (Stream);
if Transport.Is_Connected (Connection) then
Is_New := False;
else
Is_New := True;
Initialize (Stream.Stream.Transmit);
Initialize (Stream.Stream.Receive);
Stream.Stream.User_Id := 0; -- JMK 10/24/86
if Transport.Is_Open (Connection) then
Transport.Disconnect (Connection);
else
Transport.Close (Connection);
Transport.Open (Connection, Status, Network);
Check_Ok (Status);
end if;
for Retry in 0 .. Retries loop
-- JMK 5/7/87 If the remote machine refuses the connection,
-- perhaps that is because it is in the process of starting
-- a server task or job. Give it a little time to do this.
Transport.Connect (Connection, Status, Host, Socket);
exit when Transport_Defs."/="
(Status, Transport_Defs.Connection_Refused);
delay Backoff;
end loop;
Check_Ok (Status);
end if;
Transport.Set_Owner -- JMK 10/27/86
(Connection, Machine.Get_Job_Id (Machine.Get_Task_Id));
end Get_Connected;
procedure Allocate (Stream : out Stream_Id;
Pool : Pool_Id;
Is_New : out Boolean) is
The_Stream : Stream_Id;
begin
Worker.Allocate (The_Stream, Pool);
Stream := The_Stream;
Get_Connected (The_Stream, Is_New,
Pool.Network, Pool.Remote_Host, Pool.Remote_Socket);
exception
when Not_Connected | Tasking_Error =>
Disconnect (The_Stream);
raise Not_Connected;
end Allocate;
procedure Allocate (Stream : out Stream_Id;
Is_New : out Boolean;
Network : Transport_Defs.Network_Name;
Host : Transport_Defs.Host_Id;
Socket : Transport_Defs.Socket_Id) is
The_Stream : Stream_Id;
begin
Worker.Allocate (The_Stream, Network, Host, Socket);
Stream := The_Stream;
Get_Connected (The_Stream, Is_New, Network, Host, Socket);
exception
when Not_Connected | Tasking_Error =>
Disconnect (The_Stream);
raise Not_Connected;
end Allocate;
procedure Disconnect_Now (Stream : Stream_Id) is
-- JMK 2/13/87
begin
if not Is_Null (Stream) then
Worker.Disconnect (Stream);
end if;
exception
when others =>
Stream.Stream.Unique := Null_Unique_Id;
Transport.Disconnect (Stream.Stream.Connection); -- JMK 2/13/87
Transport.Close (Stream.Stream.Connection);
end Disconnect_Now;
procedure Disconnect (Stream : Stream_Id) is
begin
begin
Flush_Transmit_Buffer (Stream); -- JMK 2/13/87
exception
when others =>
null;
end;
Disconnect_Now (Stream);
end Disconnect;
procedure Deallocate (Stream : Stream_Id) is
begin
begin
Flush_Transmit_Buffer (Stream); -- JMK 2/13/87
exception
when others =>
null;
end;
if not Is_Null (Stream) then
Worker.Deallocate (Stream);
end if;
exception
when Tasking_Error =>
Disconnect_Now (Stream); -- JMK 2/13/87
end Deallocate;
function Connection (Stream : Stream_Id)
return Transport.Connection_Id is
begin
Check_Non_Null (Stream);
return Stream.Stream.Connection;
end Connection;
function Unique (Stream : Stream_Id) return Unique_Id is
begin
return Stream.Unique;
end Unique;
procedure Set_User_Id (Stream : Stream_Id; User_Id : Integer := 0) is
begin
Check_Non_Null (Stream);
Stream.Stream.User_Id := User_Id;
end Set_User_Id;
function Get_User_Id (Stream : Stream_Id) return Integer is
begin
Check_Non_Null (Stream);
return Stream.Stream.User_Id;
end Get_User_Id;
procedure Check (Status : Transport_Defs.Status_Code) is
begin
case Status is
when Transport_Defs.Ok | Transport_Defs.Timed_Out =>
null;
when others =>
raise Not_Connected;
end case;
end Check;
procedure Transmit (Connection : Transport.Connection_Id;
Data : Byte_Defs.Byte_String;
More : Boolean := False) is
Status : Transport_Defs.Status_Code;
Count : Natural;
Total : Natural := 0;
begin
loop
Transport.Transmit
(Connection, Status, Data (Data'First + Total .. Data'Last),
Count,
More => More);
Total := Total + Count;
exit when Total >= Data'Length;
Check (Status);
end loop;
end Transmit;
procedure Receive (Connection : Transport.Connection_Id;
Data : out Byte_Defs.Byte_String) is
Status : Transport_Defs.Status_Code;
Count : Natural;
Total : Natural := 0;
begin
loop
Transport.Receive
(Connection, Status, Data (Data'First + Total .. Data'Last),
Count);
Total := Total + Count;
exit when Total >= Data'Length;
Check (Status);
end loop;
end Receive;
procedure Transmit (Into : Stream_Id; Data : Byte_Defs.Byte_String) is
begin
Check_Non_Null (Into);
if Data'Length > 0 then
declare
Buf : Buffer_Type renames Into.Stream.Transmit;
Connection : Transport.Connection_Id
renames Into.Stream.Connection;
begin
pragma Assert (Buf.First = Data_Index'First);
if Buf.Count + Data'Length < Data_Count'Last then
Buf.Data
(Buf.First + Buf.Count ..
Buf.First + Buf.Count + Data'Length - 1) := Data;
Buf.Count := Buf.Count + Data'Length;
else
Transmit (Connection,
Buf.Data (Buf.First ..
Buf.First + Buf.Count - 1));
Transmit (Connection, Data);
Buf.Count := 0;
end if;
end;
end if;
exception
when Not_Connected =>
Disconnect (Into);
raise;
end Transmit;
procedure Receive (From : Stream_Id; Data : out Byte_Defs.Byte_String) is
begin
Check_Non_Null (From);
if Data'Length > 0 then
-- If its <= 0, then we're done. Receiving 0 bytes is easy.
declare
Buf : Buffer_Type renames From.Stream.Receive;
Connection : Transport.Connection_Id
renames From.Stream.Connection;
Status : Transport_Defs.Status_Code;
begin
if Buf.Count = 0 then
-- nothing at all in the buffer.
pragma Assert (Buf.First = Buf.Data'First);
if Data'Length >= Buf.Data'Length then
-- bypass the buffer: receive right into Data.
Receive (Connection, Data);
return;
else
-- wait for some data (any data) to arrive.
loop
Transport.Receive
(Connection, Status, Buf.Data, Buf.Count);
exit when Buf.Count > 0;
Check (Status);
end loop;
end if;
end if;
pragma Assert (Buf.First + Buf.Count - 1 <= Data_Index'Last);
if Buf.Count >= Data'Length then
-- All the data we need are in the buffer.
Data :=
Buf.Data (Buf.First .. Buf.First + Data'Length - 1);
Buf.Count := Buf.Count - Data'Length;
if Buf.Count = 0 then
Buf.First := Data_Index'First;
else
Buf.First := Buf.First + Data'Length;
end if;
else
-- Clean out the buffer:
Data (Data'First .. Data'First + Buf.Count - 1) :=
Buf.Data (Buf.First .. Buf.First + Buf.Count - 1);
-- Receive the rest of the data straight into Data:
Receive (Connection,
Data (Data'First + Buf.Count .. Data'Last));
Buf.First := Buf.Data'First;
Buf.Count := 0;
end if;
end;
end if;
exception
when Not_Connected =>
Disconnect (From);
raise;
end Receive;
procedure Flush_Transmit_Buffer (Stream : Stream_Id) is
begin
Check_Non_Null (Stream);
declare
Buf : Buffer_Type renames Stream.Stream.Transmit;
begin
Transmit (Stream.Stream.Connection,
Buf.Data (Buf.Data'First ..
Buf.Data'First + Buf.Count - 1),
More => False);
Buf.Count := 0;
end;
exception
when Not_Connected =>
Disconnect_Now (Stream); -- JMK 2/13/87
raise;
end Flush_Transmit_Buffer;
function Flush_Receive_Buffer
(Stream : Stream_Id) return Byte_Defs.Byte_String is
begin
Check_Non_Null (Stream);
declare
Buf : Buffer_Type renames Stream.Stream.Receive;
Answer : constant Byte_Defs.Byte_String :=
Buf.Data (Buf.First .. Buf.First + Buf.Count - 1);
begin
Buf.First := Buf.Data'First;
Buf.Count := 0;
return Answer;
end;
exception
when Not_Connected =>
Disconnect (Stream);
raise;
end Flush_Receive_Buffer;
task body Worker is separate;
end Transport_Stream;
nblk1=14
nid=0
hdr6=28
[0x00] rec0=1d rec1=00 rec2=01 rec3=06a
[0x01] rec0=1e rec1=00 rec2=02 rec3=00a
[0x02] rec0=1e rec1=00 rec2=03 rec3=00e
[0x03] rec0=1c rec1=00 rec2=04 rec3=030
[0x04] rec0=24 rec1=00 rec2=05 rec3=014
[0x05] rec0=1f rec1=00 rec2=06 rec3=010
[0x06] rec0=23 rec1=00 rec2=07 rec3=056
[0x07] rec0=1a rec1=00 rec2=08 rec3=032
[0x08] rec0=13 rec1=00 rec2=09 rec3=028
[0x09] rec0=1a rec1=00 rec2=0a rec3=00c
[0x0a] rec0=1c rec1=00 rec2=0b rec3=020
[0x0b] rec0=21 rec1=00 rec2=0c rec3=032
[0x0c] rec0=1e rec1=00 rec2=0d rec3=034
[0x0d] rec0=1d rec1=00 rec2=0e rec3=074
[0x0e] rec0=17 rec1=00 rec2=0f rec3=028
[0x0f] rec0=1b rec1=00 rec2=10 rec3=01a
[0x10] rec0=16 rec1=00 rec2=11 rec3=070
[0x11] rec0=1b rec1=00 rec2=12 rec3=054
[0x12] rec0=1d rec1=00 rec2=13 rec3=006
[0x13] rec0=08 rec1=00 rec2=14 rec3=000
tail 0x20500176a7bac64d33ef9 0x42a00088462060003