DIRECTORY Arpa USING [Address, MyAddress], Basics USING [HFromCard16], RefText USING [New], SunPMap USING [CallitProc, DumpProc, GetPortProc, ipProtocolUDP, MapEntry, NullProc, SetProc, UnsetProc], SunPMapLocal USING [], SunPMapServer USING [], SunRPC USING [BytesRemaining, Destroy, Error, GetBlock, Handle, PutBlock, SendCallAndReceiveReply, StartCall], SunRPCOnUDP USING [Create], SunRPCAuth USING [Conversation, Initiate, Terminate] ; SunPMapServerImpl: CEDAR MONITOR IMPORTS Arpa, Basics, RefText, SunRPC, SunRPCOnUDP, SunRPCAuth EXPORTS SunPMapLocal, SunPMapServer ~ { tableSize: CARDINAL ~ 31; longTimeout: CARD ¬ 5000; Address: TYPE ~ Arpa.Address; Handle: TYPE ~ SunRPC.Handle; Conversation: TYPE ~ SunRPCAuth.Conversation; MapEntry: TYPE ~ SunPMap.MapEntry; Item: TYPE ~ REF ItemObject; ItemObject: TYPE ~ RECORD [ next: Item, entry: MapEntry ]; Headers: TYPE ~ REF HeadersObject; HeadersObject: TYPE ~ ARRAY [0 .. tableSize) OF Item; headers: Headers ¬ NEW[HeadersObject]; Hash: PROC [program, version: CARD] RETURNS [CARD] ~ { RETURN [(3*program + version) MOD tableSize]; }; Null: PUBLIC SunPMap.NullProc -- [h: Handle, c: Conversation] -- ~ { NULL; }; Set: PUBLIC SunPMap.SetProc -- [h: Handle, c: Conversation, program, version, protocol, port: CARD32] RETURNS [success: BOOL] -- ~ { RETURN [SetLocal[program, version, protocol, port]]; }; SetLocal: PUBLIC ENTRY PROC [program, version, protocol, port: CARD32] RETURNS [success: BOOL] ~ { index: CARD ¬ Hash[program, version]; FOR item: Item ¬ headers[index], item.next WHILE item # NIL DO IF (item.entry.program = program) AND (item.entry.version = version) AND (item.entry.protocol = protocol) AND (item.entry.port = port) THEN RETURN [FALSE]; ENDLOOP; headers[index] ¬ NEW[ItemObject ¬ [headers[index], [program, version, protocol, port]]]; RETURN [TRUE]; }; Unset: PUBLIC SunPMap.UnsetProc -- [h: Handle, c: Conversation, program, version: CARD32] RETURNS [success: BOOL] -- ~ { RETURN [UnsetLocal[program, version]]; }; UnsetLocal: PUBLIC ENTRY PROC [program, version: CARD32] RETURNS [success: BOOL] ~ { prev, p: Item; index: CARD ¬ Hash[program, version]; success ¬ FALSE; prev ¬ NIL; p ¬ headers[index]; DO IF p = NIL THEN RETURN; IF (p.entry.program = program) AND (p.entry.version = version) THEN { success ¬ TRUE; IF prev = NIL THEN headers[index] ¬ p.next ELSE prev.next ¬ p.next; } ELSE { prev ¬ p; }; p ¬ p.next; ENDLOOP; }; GetPort: PUBLIC SunPMap.GetPortProc -- [h: Handle, c: Conversation, program, version, protocol: CARD32] RETURNS [port: CARD32] -- ~ { RETURN [GetPortLocal[program, version, protocol]]; }; GetPortLocal: PUBLIC ENTRY PROC [program, version, protocol: CARD32] RETURNS [port: CARD32] ~ { index: CARD ¬ Hash[program, version]; FOR item: Item ¬ headers[index], item.next WHILE item # NIL DO IF (item.entry.program = program) AND (item.entry.version = version) AND (item.entry.protocol = protocol) THEN RETURN [item.entry.port]; ENDLOOP; RETURN [0]; }; Dump: PUBLIC SunPMap.DumpProc -- [h: Handle, c: Conversation, eachMapEntry: PROC[MapEntry]] -- ~ { DumpLocal[eachMapEntry]; }; DumpLocal: PUBLIC PROC [eachMapEntry: PROC[MapEntry]] ~ { FOR i: CARDINAL IN [0 .. tableSize) DO FOR p: Item ¬ headers[i], p.next WHILE p # NIL DO eachMapEntry[p.entry]; ENDLOOP; ENDLOOP; }; Callit: PUBLIC SunPMap.CallitProc -- [h: Handle, c: Conversation, program, version, proc: CARD32, args: REF TEXT] RETURNS [port: CARD32, result: REF TEXT] -- ~ { gotError: BOOL ¬ FALSE; [port, result] ¬ CallitLocal[program, version, proc, args, longTimeout, 0 ! SunRPC.Error => { gotError ¬ TRUE; CONTINUE }]; IF gotError THEN ERROR SunRPC.Error[$abortWithoutReturn]; }; CallitLocal: PUBLIC PROC [program, version, proc: CARD32, args: REF TEXT, timeout: CARD, retries: CARD] RETURNS [port: CARD32, result: REF TEXT] ~ { hLocal: Handle ¬ NIL; conversation: Conversation ¬ NIL; CleanUp: PROC ~ { IF hLocal # NIL THEN { SunRPC.Destroy[hLocal]; hLocal ¬ NIL }; IF conversation # NIL THEN { SunRPCAuth.Terminate[conversation]; conversation ¬ NIL }; }; { ENABLE UNWIND => CleanUp[]; bytes: CARDINAL; port ¬ GetPortLocal[program, version, SunPMap.ipProtocolUDP]; IF port = 0 THEN ERROR SunRPC.Error[$serviceNotRegistered]; hLocal ¬ SunRPCOnUDP.Create[remoteAddress~Arpa.MyAddress[], remotePort~Basics.HFromCard16[port]]; conversation ¬ SunRPCAuth.Initiate[]; SunRPC.StartCall[hLocal, conversation, program, version, proc]; SunRPC.PutBlock[hLocal, args, 0, args.length]; [] ¬ SunRPC.SendCallAndReceiveReply[hLocal, timeout, retries]; bytes ¬ SunRPC.BytesRemaining[hLocal]; result ¬ RefText.New[bytes]; SunRPC.GetBlock[hLocal, result, 0, bytes]; }; CleanUp[]; }; }... Z SunPMapServerImpl.mesa Copyright Σ 1987, 1991, 1992 by Xerox Corporation. All rights reserved. Demers, November 4, 1987 11:47:53 am PST Willie-s, August 21, 1991 12:40 pm PDT Chauser, January 3, 1992 10:57 am PST Parameters Types Map Procedures It's okay to do this without holding the monitor lock because REF operations are atomic ... Κρ–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ=™HK™(K™&K™%K˜—šΟk ˜ Kšœžœ˜ Kšœžœ˜Kšœžœ˜Kšœžœ\˜iKšœ žœ˜Kšœžœ˜Kšœžœb˜nKšœ žœ ˜Kšœ žœ$˜4K˜K˜—šΟnœžœž˜ Kšžœ7˜>Kšžœ˜#K˜head™ Kšœ žœ˜Kšœ žœ˜—™Kšœ žœ˜K˜Kšœžœ˜Kšœžœ˜-K˜Kšœ žœ˜"—™Kšœžœžœ ˜šœ žœžœ˜K˜ K˜K˜K˜—Kšœ žœžœ˜"Kšœžœžœžœ˜5K˜Kšœžœ˜&K˜š Ÿœžœžœžœžœ˜6Kšžœžœ ˜-K˜——™ šŸœžœΟc"œ˜DKšžœ˜K˜K˜—šŸœžœ dœ˜„Kšžœ.˜4K˜K˜—šŸœžœžœžœ$žœžœ žœ˜bKšœžœ˜%šžœ(žœžœž˜>šžœ žœ žœ"žœ˜†Kšžœžœžœ˜—Kšžœ˜—KšœžœD˜XKšžœžœ˜K˜K˜—šŸœžœ Tœ˜xKšžœ ˜&K˜K˜—šŸ œžœžœžœžœžœ žœ˜TK˜Kšœžœ˜%Kšœ žœ˜Kšœžœ˜šž˜Kšžœžœžœžœ˜šžœžœ˜>šžœ˜Kšœ žœ˜Kšžœžœžœžœ˜CK˜—šžœ˜K˜ K˜——K˜ Kšžœ˜—K˜K˜—šŸœžœ ]œ˜…Kšžœ,˜2K˜K˜—šŸ œžœžœžœžœžœžœ˜_Kšœžœ˜%šžœ(žœžœž˜>šžœ žœ žœ!˜iKšžœžœ˜—Kšžœ˜—Kšžœ˜ K˜K˜—šŸœžœ @œ˜bKšœ˜K˜K˜—šŸ œžœžœžœ˜9K™[šžœžœžœž˜&šžœžœžœž˜1Kšœ˜Kšžœ˜—Kšžœ˜—K˜K˜—šŸœžœ {œ˜‘Kšœ žœžœ˜Kšœižœžœ˜{Kšžœ žœžœ#˜9K˜K˜—šŸ œžœžœžœžœžœ žœ žœžœžœ žœžœ˜”Kšœžœ˜Kšœžœ˜!šŸœžœ˜Kšžœ žœ$žœ˜>Kšžœžœ6žœ˜VK˜—K˜šœžœžœ˜Kšœžœ˜Kšœ=˜=Kšžœ žœžœ%˜;Kšœa˜aK˜%Kšœ?˜?Kšœ.˜.Kšœ>˜>Kšœ&˜&Kšœ˜Kšœ*˜*K˜—K˜ K˜K˜——K˜—K˜—…—(s