<> <> <> <> <> 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; <> 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 <> UNTIL quit DO UNTIL userTest DO Process.Pause[Process.SecondsToTicks[5]]; ENDLOOP; conversation _ RPC.StartConversation[callerName, callerKey, exporterName, authOnly]; senderPage _ 0; StartTransfer[conversation]; <> <> 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]; <> <> <> JOIN first; JOIN second; JOIN third; JOIN fourth; <> <> <> end _ BasicTime.GetClockPulses[]; <> elapsed _ BasicTime.PulsesToMicroseconds[end-start]; RPC.EndConversation[conversation]; IF signalFinished THEN SIGNAL Finished[]; END; ENDLOOP; END; END; DoIt[]; END.