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
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] ];
};
};
}...