RPCBulk.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Andrew Birrell 26-Feb-82 10:06:00
Bob Hagmann February 11, 1985 10:15:18 am PST
Hal Murray, January 20, 1986 7:31:00 pm PST
DIRECTORY
BasicTime USING [GetClockPulses, Pulses, PulsesToMicroseconds],
Process USING [Pause, SecondsToTicks],
Rope USING [ROPE],
RPC USING [Conversation, EncryptionKey, EndConversation, ImportFailed, MakeKey, Principal, StartConversation],
RPCLupine USING [Call, DataLength, Dispatcher, ExportInterface, ImportHandle, ImportInterface, GetStubPkt, maxDataLength, pktOverhead, StartCall, StubPkt];
RPCBulk: MONITOR
IMPORTS BasicTime, Process, RPC, RPCLupine =
BEGIN
-- ******** Test program ******** --
Finished: SIGNAL = CODE;
signalFinished: BOOLEANTRUE;
tries: CARDINAL ← 1000;
quit: BOOLEANFALSE;
gvExport: BOOLEANTRUE;
gvInstance: Rope.ROPE = "RPCRuntime.pa";
nongvInstance: Rope.ROPE = "Tokay";
callerName: RPC.Principal ← "Test.pa";
callerKey: RPC.EncryptionKey ← RPC.MakeKey["Test"];
exporterName: RPC.Principal ← "RPCRuntime.pa";
exporterKey: RPC.EncryptionKey ← RPC.MakeKey["zzy"];
userTest: BOOLEANTRUE;
spyWanted: BOOLEANFALSE;
import: RPCLupine.ImportHandle ← NIL;
-- Test version of stub code --
StartTransfer: PROC[conv: RPC.Conversation] =
BEGIN
pktSpace: ARRAY [0..RPCLupine.pktOverhead+1) OF WORD;
pkt: RPCLupine.StubPkt = RPCLupine.GetStubPkt[@pktSpace];
[] ← RPCLupine.StartCall[pkt, import, conv];
BEGIN
length: RPCLupine.DataLength;
last: BOOLEAN;
pkt[0] ← 1;
[length, last] ← RPCLupine.Call[pkt, 1, 1, NIL];
IF ~last THEN ERROR;
END;
END;
SendPage: PROC[conv: RPC.Conversation, page: CARDINAL] =
BEGIN
pktSpace: ARRAY [0..RPCLupine.pktOverhead+RPCLupine.maxDataLength) OF WORD;
pkt: RPCLupine.StubPkt = RPCLupine.GetStubPkt[@pktSpace];
[] ← RPCLupine.StartCall[pkt, import, conv];
BEGIN
length: RPCLupine.DataLength;
last: BOOLEAN;
pkt[0] ← 0; pkt[1] ← page;
[length, last] ← RPCLupine.Call[pkt, RPCLupine.maxDataLength,
RPCLupine.maxDataLength, NIL];
IF ~last THEN ERROR;
END;
END;
TestDispatcher: RPCLupine.Dispatcher =
BEGIN
-- Dummy dispatcher: consumes args and sends dummy result --
IF ~lastPkt THEN ERROR;
SELECT pkt[0] FROM
0 => AcceptPage[localConversation, pkt[1] ];
1 => AcceptTransfer[localConversation];
ENDCASE => ERROR;
RETURN[0];
END;
-- Test version of client code --
-- Sender --
conversation: RPC.Conversation;
senderPage: CARDINAL ← 0;
NextPage: ENTRY PROC RETURNS [p: CARDINAL] = INLINE
{ p ← senderPage; senderPage ← senderPage+1 };
Sender: PROC [limit: CARDINAL] =
BEGIN
DO p: CARDINAL = NextPage[];
IF p > limit THEN EXIT;
SendPage[conversation, p];
ENDLOOP;
END;
-- Receiver --
pageCond: CONDITION ← [timeout:0];
receiverPage: CARDINAL ← 0;
AcceptTransfer: ENTRY PROC [conv: RPC.Conversation] =
BEGIN
receiverPage ← 0;
END;
AcceptPage: ENTRY PROC [conv: RPC.Conversation, page: CARDINAL] =
BEGIN
UNTIL receiverPage = page DO WAIT pageCond ENDLOOP;
receiverPage ← page + 1;
BROADCAST pageCond;
END;
DoIt: PROC =
BEGIN
-- Export and import --
instance: Rope.ROPEIF gvExport THEN gvInstance ELSE nongvInstance;
import ← RPCLupine.ImportInterface[["RPC-bulk-test", instance], [0,0] !
RPC.ImportFailed =>
IF why = unbound OR why = communications THEN {
[] ← RPCLupine.ExportInterface[exporterName, exporterKey,
["RPC-bulk-test", instance], TestDispatcher, [0,0]];
import ← RPCLupine.ImportInterface[["RPC-bulk-test",
instance],[0,0]];
CONTINUE; } ];
BEGIN
spyAvailable: BOOLEAN = Runtime.IsBound[SpyClient.StartCounting];
UNTIL quit
DO UNTIL userTest DO
Process.Pause[Process.SecondsToTicks[5]]; ENDLOOP;
conversation ← RPC.StartConversation[callerName, callerKey, exporterName, authOnly];
senderPage ← 0;
StartTransfer[conversation];
NameInfoSpecialDefs.CleanUp[];
IF spyWanted AND spyAvailable THEN SpyClient.StartCounting[];
BEGIN
start: BasicTime.Pulses = BasicTime.GetClockPulses[];
end: BasicTime.Pulses;
elapsed: LONG CARDINAL;
first: PROCESS = FORK Sender[tries];
second: PROCESS = FORK Sender[tries];
third: PROCESS = FORK Sender[tries];
fourth: PROCESS = FORK Sender[tries];
fifth: PROCESS = FORK Sender[tries];
sixth: PROCESS = FORK Sender[tries];
seventh: PROCESS = FORK Sender[tries];
JOIN first;
JOIN second;
JOIN third;
JOIN fourth;
JOIN fifth;
JOIN sixth;
JOIN seventh;
end ← BasicTime.GetClockPulses[];
IF spyWanted AND spyAvailable THEN SpyClient.StopCounting[];
elapsed ← BasicTime.PulsesToMicroseconds[end-start];
RPC.EndConversation[conversation];
IF signalFinished THEN SIGNAL Finished[];
END;
ENDLOOP;
END;
END;
DoIt[];
END.