DIRECTORY CrRPC USING [Call, CreateClientHandle, DestroyClientHandle, GetCARDINAL, GetFWORD, GetHWORD, GetResultsProc, Handle, PutArgsProc, PutCARD, PutCARDINAL, SetHops, SetTimeout], Endian USING [FWORD, HWORD], XNS USING [broadcastHost, broadcastNet, unknownAddress], CourierBindingProtocol, CourierBinding; CourierBindingClientImpl: CEDAR PROGRAM IMPORTS CrRPC EXPORTS CourierBinding ~ { OPEN CourierBindingProtocol; CARD: TYPE ~ LONG CARDINAL; FWORD: TYPE ~ Endian.FWORD; HWORD: TYPE ~ Endian.HWORD; AddressList: TYPE ~ LIST OF Address; Handle: TYPE ~ CrRPC.Handle; BASICTIMEOUT: CARDINAL _ 200; ROUTERDELAY: CARDINAL _ 300; RETRIES: CARDINAL _ 4; TimeoutHeuristic: PROC [hops: CARDINAL] RETURNS [CARDINAL] ~ INLINE { RETURN [BASICTIMEOUT + (ROUTERDELAY * hops)]; }; AddToAddressList: PROC [new: Address, list: AddressList] RETURNS [AddressList] ~ { FOR temp: AddressList _ list, temp.rest WHILE (temp # NIL) DO IF (temp.first = new) THEN RETURN [list]; ENDLOOP; RETURN [ CONS[new, list] ]; }; Bind: PUBLIC PROC [predicate: CARD, versions: Range, maxHops: CARDINAL, stubPutPred: CrRPC.PutArgsProc] RETURNS [answer: Address _ XNS.unknownAddress] ~ { answerList: AddressList _ AddToAddressList[answer, NIL]; h: Handle _ CrRPC.CreateClientHandle[ class~$EXCHANGE, remote~[net~XNS.broadcastNet, host~XNS.broadcastHost, socket~socket], timeoutMsec~BASICTIMEOUT]; { FOR hops: CARDINAL IN [0..maxHops] DO IF TRUE THEN h _ CrRPC.SetHops[h~h, low~hops, high~hops]; h _ CrRPC.SetTimeout[h, TimeoutHeuristic[hops]]; THROUGH [0..RETRIES) DO answerList _ RingPredicate[h, answerList, predicate, versions, stubPutPred]; IF (answerList.first # XNS.unknownAddress) THEN GOTO Found; ENDLOOP; ENDLOOP; EXITS Found => { answer _ answerList.first; }; -- maybe first isn't best? }; CrRPC.DestroyClientHandle[h]; }; GetRange: PROC [h: Handle] RETURNS [r: Range] ~ { r.lowVersion _ CrRPC.GetCARDINAL[h]; r.highVersion _ CrRPC.GetCARDINAL[h]; }; PutRange: PROC [h: Handle, r: Range] ~ { CrRPC.PutCARDINAL[h, r.lowVersion]; CrRPC.PutCARDINAL[h, r.highVersion]; }; GetXNSAddress: PROC [h: Handle] RETURNS [Address] ~ { xNet: FWORD; xHost: MACHINE DEPENDENT RECORD [a, b, c: HWORD]; xSocket: HWORD; xNet _ CrRPC.GetFWORD[h]; xHost.a _ CrRPC.GetHWORD[h]; xHost.b _ CrRPC.GetHWORD[h]; xHost.c _ CrRPC.GetHWORD[h]; xSocket _ CrRPC.GetHWORD[h]; TRUSTED { RETURN [ [net~LOOPHOLE[xNet], host~LOOPHOLE[xHost], socket~LOOPHOLE[xSocket]] ] }; }; RingPredicate: PROC [h: Handle, oldList: AddressList, predicate: CARD, versions: Range, stubPutPred: CrRPC.PutArgsProc] RETURNS [newList: AddressList] ~ { PutArgs: CrRPC.PutArgsProc ~ { CrRPC.PutCARD[h, predicate]; PutRange[h, versions]; IF (stubPutPred # NIL) THEN stubPutPred[h]; }; GetResults: CrRPC.GetResultsProc ~ { r: Range _ GetRange[h]; newList _ AddToAddressList[GetXNSAddress[h], newList]; }; newList _ oldList; CrRPC.Call[h~h, remotePgm~program, remotePgmVersion~version, remoteProc~bind, putArgs~PutArgs, getResults~GetResults ]; }; }... ^CourierBindingClientImpl.mesa Copyright (C) 1985, 1986 by Xerox Corporation. All rights reserved. kam 17-Jan-86 10:45:56 Bill Jackson (bj) June 23, 1986 1:13:50 pm PDT Types Magic Stuff Procs h _ CrRPC.CreateClientHandle[ class~$EXCHANGE, remote~XNSName.AddressFromRope["1234B.25205403463B.1750B"], timeoutMsec~BASICTIMEOUT]; Êx˜šœ™JšœD™DJšœ&™&Icode™.—J˜šÏk ˜ Kšœœ¢˜­Kšœœœœ˜Kšœœ/˜8Kšœ˜Kšœ˜—J˜šÏnœœ˜'Jšœ˜ Jšœ˜Jšœ˜—J˜šœ™J˜Jšœœœœ˜Kšœœ œ˜Kšœœ œ˜Kšœ œœœ ˜$Kšœœ˜J˜—™ J˜JšÐbk œœ˜JšŸ œœ˜JšŸœœ˜J˜š žœœœœœœ˜EJšÏbœŸ œŸ œ ˜-Jšœ˜—J˜—šœ™J˜šžœœ#œ˜Rš œ%œœœ˜=Kšœœœ˜)Kšœ˜—Kšœœ˜K˜K˜—šžœœœ œœ"œœ˜šKšœ3œ˜8šœ%˜%Kšœ˜Kšœ œœ œ˜EKšœ Ÿ œ˜—šœ™Kšœ™Kšœ;™;Kšœ Ÿ œ™—š˜šœœœ˜%Kšœœœ-˜9Kšœ œ˜0šœŸœ˜KšœK˜LKšœœœœ˜;Kšœ˜—Kšœ˜—š˜Kšœ)Ïc˜C—Kšœ˜—Kšœ˜K˜K˜—šžœœ œ˜1Kšœ$˜$Kšœ%˜%K˜K˜—šžœœ˜)Kšœ#˜#Kšœ$˜$K˜K˜—šž œœ œ˜5Kšœœ˜ Kš œœ œœ œ˜1Kšœ œ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜šœœ˜Kšœœ œœ˜I—K˜K˜—šž œœ.œ2œ˜šK˜šžœ˜Kšœ˜Kšœ˜Kšœœœ˜+Kšœ˜K˜—šž œ˜$Jšœ˜Kšœ6˜6K˜K˜—K˜šœ œ œ  œ(˜tKšœ˜—K˜K˜——šœ˜J˜J˜J˜—J˜—…— ®„