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: BOOLEAN ← TRUE;
tries: CARDINAL ← 1000;
quit: BOOLEAN ← FALSE;
gvExport: BOOLEAN ← TRUE;
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: BOOLEAN ← TRUE;
spyWanted: BOOLEAN ← FALSE;
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.ROPE ← IF 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.