-- RPCTest.mesa -- Andrew Birrell January 27, 1983 10:40 am DIRECTORY Process, MesaRPC, RPCLupine, Runtime, SpyClient, System; RPCTest: MONITOR IMPORTS Process, MesaRPC, RPCLupine, Runtime, SpyClient, System = BEGIN -- ******** Test program ******** -- Finished: SIGNAL = CODE; signalFinished: BOOLEAN ← TRUE; extraArgPkts: CARDINAL ← 0; extraArgLength: RPCLupine.DataLength ← RPCLupine.maxDataLength-1; argLength: RPCLupine.DataLength ← 1; extraResPkts: CARDINAL ← 0; extraResLength: RPCLupine.DataLength ← RPCLupine.maxDataLength; resLength: RPCLupine.DataLength ← 2; callDelaySecs: CARDINAL ← 0; senderGapSecs: CARDINAL ← 0; receiverGapSecs:CARDINAL ← 0; callGapSecs: CARDINAL ← 0; tries: CARDINAL ← 1000; quit: BOOLEAN ← FALSE; raiseSignal: BOOLEAN ← FALSE; resumeSignal: BOOLEAN ← TRUE; authenticate: BOOLEAN ← TRUE; gvExport: BOOLEAN ← TRUE; gvInstance: STRING = "RPCRuntime.pa"; nongvInstance: STRING = "Tokay"; callerName: MesaRPC.Principal ← "Test.pa"; callerKey: MesaRPC.EncryptionKey ← MesaRPC.MakeKey["Test"L]; exporterName: MesaRPC.Principal ← "RPCRuntime.pa"; exporterKey: MesaRPC.EncryptionKey ← MesaRPC.MakeKey["zzy"L]; userTest: BOOLEAN ← TRUE; spyWanted: BOOLEAN ← FALSE; minWanted: BOOLEAN ← TRUE; caller: PROCESS; pktSpace: ARRAY[1..RPCLupine.pktOverhead+RPCLupine.maxDataLength] OF WORD; pkt: RPCLupine.StubPkt = RPCLupine.GetStubPkt[@pktSpace]; import: RPCLupine.ImportHandle ← NIL; conversation: MesaRPC.Conversation; -- Test version of stub code -- RemoteSignal: SIGNAL = CODE; SignalDispatcher: RPCLupine.Dispatcher = BEGIN UNTIL lastPkt DO [callLength,lastPkt] ← RPCLupine.ReceiveExtraPkt[pkt] ENDLOOP; SIGNAL RemoteSignal[]; RETURN[0] END; Send: PROC = BEGIN [] ← RPCLupine.StartCall[pkt, import, conversation]; FOR p: CARDINAL IN [1..extraArgPkts] DO RPCLupine.SendPrelimPkt[pkt, extraArgLength]; IF senderGapSecs > 0 THEN Process.Pause[Process.SecondsToTicks[senderGapSecs]]; ENDLOOP; BEGIN length: RPCLupine.DataLength; last: BOOLEAN; [length, last] ← RPCLupine.Call[pkt, argLength, RPCLupine.maxDataLength, SignalDispatcher]; UNTIL last DO IF receiverGapSecs > 0 THEN Process.Pause[Process.SecondsToTicks[receiverGapSecs]]; [length, last] ← RPCLupine.ReceiveExtraPkt[pkt]; ENDLOOP; END; END; TestDispatcher: RPCLupine.Dispatcher = BEGIN -- Dummy dispatcher: consumes args and sends dummy result -- UNTIL lastPkt DO IF receiverGapSecs > 0 THEN Process.Pause[Process.SecondsToTicks[receiverGapSecs]]; [callLength,lastPkt] ← RPCLupine.ReceiveExtraPkt[pkt]; ENDLOOP; Client[ ! RemoteSignal => BEGIN RPCLupine.StartSignal[pkt]; [callLength,lastPkt] ← RPCLupine.Call[pkt, 0, RPCLupine.maxDataLength, NIL]; UNTIL lastPkt DO [callLength,lastPkt] ← RPCLupine.ReceiveExtraPkt[pkt] ENDLOOP; RESUME END ]; IF callDelaySecs > 0 THEN Process.Pause[Process.SecondsToTicks[callDelaySecs]]; FOR res: CARDINAL IN [1..extraResPkts] DO RPCLupine.SendPrelimPkt[pkt,extraResLength]; IF senderGapSecs > 0 THEN Process.Pause[Process.SecondsToTicks[senderGapSecs]]; ENDLOOP; RETURN[resLength]; END; -- Test version of client code -- Client: PROC = { IF raiseSignal THEN SIGNAL RemoteSignal[] }; -- remote procedure being called! -- instance: STRING ← IF gvExport THEN gvInstance ELSE nongvInstance; exported: BOOLEAN ← FALSE; expHandle: RPCLupine.ExportHandle; Work: PROC = BEGIN import ← RPCLupine.ImportInterface[["RPC-Test"L, instance], [0,0] ! MesaRPC.ImportFailed => IF why = unbound OR why = communications THEN BEGIN expHandle ← RPCLupine.ExportInterface[exporterName, exporterKey, ["RPC-Test"L, instance], TestDispatcher, [0,0]]; exported ← TRUE; import ← RPCLupine.ImportInterface[["RPC-Test"L, instance],[0,0]]; CONTINUE END ]; BEGIN spyAvailable: BOOLEAN = Runtime.IsBound[SpyClient.StartSpy]; DO UNTIL userTest OR quit DO Process.Pause[Process.SecondsToTicks[5]] ENDLOOP; IF quit THEN EXIT; conversation ← IF authenticate THEN MesaRPC.StartConversation[callerName, callerKey, exporterName, CBCCheck] ELSE MesaRPC.unencrypted; Send[! RemoteSignal => IF resumeSignal THEN RESUME ELSE CONTINUE]; Send[! RemoteSignal => IF resumeSignal THEN RESUME ELSE CONTINUE]; IF spyWanted AND spyAvailable THEN SpyClient.StartSpy[]; BEGIN start: System.Pulses = System.GetClockPulses[]; end: System.Pulses; minPulses: LONG CARDINAL ← LAST[LONG CARDINAL]; elapsed: System.Microseconds; minTime: System.Microseconds; FOR call: CARDINAL IN [1..tries] DO thisStart: System.Pulses; thisPulses: LONG CARDINAL; IF minWanted THEN thisStart ← System.GetClockPulses[]; Send[! RemoteSignal => IF resumeSignal THEN RESUME ELSE CONTINUE]; IF minWanted THEN BEGIN IF thisPulses < minPulses THEN minPulses ← thisPulses; thisPulses ← System.GetClockPulses[] - thisStart; END; IF callGapSecs > 0 THEN Process.Pause[Process.SecondsToTicks[callGapSecs]]; ENDLOOP; end ← System.GetClockPulses[]; IF spyWanted AND spyAvailable THEN SpyClient.StopSpy[]; elapsed ← System.PulsesToMicroseconds[[end-start]]; minTime ← System.PulsesToMicroseconds[[minPulses]]; IF authenticate THEN MesaRPC.EndConversation[conversation]; IF signalFinished THEN SIGNAL Finished[]; END; ENDLOOP; END; IF exported THEN [] ← RPCLupine.UnexportInterface[expHandle]; END; caller ← FORK Work[]; END.