BridgeCommImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Demers, February 13, 1991 12:39 pm PST
Peter B. Kessler February 25, 1988 12:04:29 pm PST
Tim Diebert: August 30, 1989 5:57:32 am PDT
Chauser, April 14, 1993 10:22 am PDT
DIRECTORY
BridgeComm,
BridgeExec,
IO,
NetworkStream,
Process,
Rope
;
BridgeCommImpl: CEDAR PROGRAM
IMPORTS IO, NetworkStream, Process, Rope
EXPORTS BridgeComm
~ {
ROPE: TYPE ~ Rope.ROPE;
NetworkStreamPair: TYPE ~ BridgeExec.NetworkStreamPair;
Error: PUBLIC ERROR [msg: ROPE] ~ CODE;
GetRopeToEOM: PUBLIC PROC [nsp: NetworkStreamPair] RETURNS [rope: ROPE ¬ NIL] ~ {
Read to EOM and return chars read as a rope. Clear the EndOfStream condition.
rope ¬ IO.GetRope[nsp.in];
DO {
state: NetworkStream.StreamState;
[streamState~state] ¬ NetworkStream.GetStreamState[nsp.in, TRUE];
IF state = open OR state = remoteClosed THEN EXIT;
} ENDLOOP;
};
GetMsg: PUBLIC PROC [nsp: NetworkStreamPair] RETURNS [msg: CHAR, arg: ROPE] ~ {
ENABLE {
NetworkStream.Error -- [..., msg] -- => ERROR Error[msg];
IO.Error -- [..., stream] -- => ERROR Error[ Rope.Concat["I/O error", NetworkStream.GetIOErrorDetails[stream].msg ]];
IO.EndOfStream => ERROR Error["end of stream"];
};
msg ¬ IO.GetChar[nsp.in];
arg ¬ GetRopeToEOM[nsp];
};
PutMsg: PUBLIC PROC [nsp: NetworkStreamPair, msg: CHAR, arg: ROPE ¬ NIL] ~ {
ENABLE {
NetworkStream.Error -- [..., msg] -- => ERROR Error[msg];
NetworkStream.Timeout -- [..., msg] -- => ERROR Error["timeout"];
IO.Error -- [..., stream] -- => ERROR Error[ Rope.Concat["I/O error", NetworkStream.GetIOErrorDetails[stream].msg ]];
};
IO.PutChar[nsp.out, msg];
IO.PutRope[nsp.out, arg];
NetworkStream.SendEndOfMessage[nsp.out];
};
PutMsgWithReply: PUBLIC PROC [nsp: NetworkStreamPair, msg: CHAR, arg: ROPE ¬ NIL]
RETURNS [ansMsg: CHAR, ansArg: ROPE] ~ {
PutMsg[nsp, msg, arg];
NetworkStream.SendSoon[nsp.out, 0];
[ansMsg, ansArg] ¬ GetMsg[nsp];
};
PutMsgWithAck: PUBLIC PROC [nsp: NetworkStreamPair, msg: CHAR, arg: ROPE ¬ NIL] ~ {
ansMsg: CHAR;
ansArg: ROPE;
PutMsg[nsp, msg, arg];
NetworkStream.SendSoon[nsp.out, 0];
[ansMsg, ansArg] ¬ GetMsg[nsp];
IF ansMsg # 'Y THEN ERROR Error[ IF ansMsg = 'N THEN ansArg ELSE NIL ];
};
closeRequestSST: NetworkStream.SubStreamType ¬ 254;
closeReplySST: NetworkStream.SubStreamType ¬ 255;
CloseConnectionWorker: PROC [nsp: NetworkStreamPair, action: BridgeComm.CloseHandshakeAction] ~ {
SELECT action FROM
initiate => IF nsp.out # NIL THEN {
ENABLE IO.Error, NetworkStream.Error, NetworkStream.Timeout => CONTINUE;
NetworkStream.SetTimeout[nsp.out, 2000];
NetworkStream.SetSubStreamType[nsp.out, closeRequestSST];
NetworkStream.SendSoon[nsp.out, 0];
};
ENDCASE;
SELECT action FROM
initiate => IF nsp.in # NIL THEN {
ENABLE IO.Error, IO.EndOfStream, NetworkStream.Error, NetworkStream.Timeout => CONTINUE;
reply: NetworkStream.SubStreamType;
state: NetworkStream.StreamState;
NetworkStream.SetTimeout[nsp.in, 2000];
DO
IO.Reset[nsp.in];
[streamState~state, subStreamType~reply] ¬ NetworkStream.GetStreamState[nsp.in, TRUE];
IF state = remoteClosed THEN EXIT;
IF reply = closeReplySST THEN EXIT;
ENDLOOP;
};
ENDCASE;
IF nsp.in # NIL THEN {
ENABLE IO.Error, IO.EndOfStream, NetworkStream.Error, NetworkStream.Timeout => CONTINUE;
IO.Close[nsp.in, TRUE];
};
SELECT action FROM
initiate, reply => IF nsp.out # NIL THEN {
ENABLE IO.Error, NetworkStream.Error, NetworkStream.Timeout => CONTINUE;
NetworkStream.SetTimeout[nsp.out, 2000];
NetworkStream.SetSubStreamType[nsp.out, closeReplySST];
NetworkStream.SendSoon[nsp.out, 0];
NetworkStream.WaitAck[nsp.out, 2000];
};
ENDCASE => NULL;
IF nsp.out # NIL THEN {
ENABLE IO.Error, NetworkStream.Error, NetworkStream.Timeout => CONTINUE;
IO.Close[nsp.out, TRUE];
};
};
CloseConnection: PUBLIC PROC [nsp: NetworkStreamPair, action: BridgeComm.CloseHandshakeAction] ~ {
TRUSTED {
Process.Detach[ FORK CloseConnectionWorker[nsp, action] ];
};
};
}...