DIRECTORY Basics USING [Card16FromH, FWORD, HFromCard16, HWORD], CrRPC USING [BulkDataSink, BulkDataSource, ErrorReason, GetCard16, GetHWord, Handle, HandleClass, HandleKind, Object, ProcsObject, PutCard16, RefAddress, SeqCard16, SeqCard16Object, SeqHWord, SeqHWordObject, ServerProc, StopServerQueryProc], CrRPCBackdoor USING [CreateClientHandleProc, StartServerInstanceProc], FinalizeOps USING [CallQueue, CreateCallQueue, EnableFinalization, FinalizeProc, Handle, ReenableFinalization], IO USING [EndOfStream, GetChar, GetRope, PutChar, PutRope, STREAM, UnsafeGetBlock, UnsafePutBlock], RefTab USING [Create, Fetch, Ref, Store], Rope USING [Length, ROPE]; CrRPCImpl: CEDAR MONITOR IMPORTS Basics, CrRPC, FinalizeOps, RefTab, Rope EXPORTS CrRPC, CrRPCBackdoor ~ { FWORD: TYPE ~ Basics.FWORD; HWORD: TYPE ~ Basics.HWORD; ROPE: TYPE ~ Rope.ROPE; Handle: TYPE ~ CrRPC.Handle; STREAM: TYPE ~ IO.STREAM; bigEndianHWords: BOOL ~ (LOOPHOLE[Basics.HFromCard16[1], CARD16] = 1); -- ???? Error: PUBLIC ERROR [ h: Handle, errorReason: CrRPC.ErrorReason, text: ROPE] ~ CODE; CreateClientHandleProcValue: TYPE ~ REF CreateClientHandleProcValueObject; CreateClientHandleProcValueObject: TYPE ~ RECORD [ createClientHandleProc: CrRPCBackdoor.CreateClientHandleProc ]; createClientHandleProcTable: RefTab.Ref ¬ RefTab.Create[]; RegisterCreateClientHandleProc: PUBLIC PROC [ class: ATOM, proc: CrRPCBackdoor.CreateClientHandleProc] ~ { [] ¬ RefTab.Store[x~createClientHandleProcTable, key~class, val~NEW[CreateClientHandleProcValueObject ¬ [proc]]]; }; LookupCreateClientHandleProc: PROC [class: ATOM] RETURNS [CrRPCBackdoor.CreateClientHandleProc] ~ { found: BOOL; val: REF; [found, val] ¬ RefTab.Fetch[x~createClientHandleProcTable, key~class]; IF found THEN RETURN [NARROW[val, CreateClientHandleProcValue].createClientHandleProc] ELSE RETURN [NIL]; }; CreateClientHandle: PUBLIC PROC [class: ATOM, remote: CrRPC.RefAddress] RETURNS [CrRPC.Handle] ~ { proc: CrRPCBackdoor.CreateClientHandleProc ~ LookupCreateClientHandleProc[class]; IF proc = NIL THEN ERROR Error[NIL, unknownClass, NIL]; RETURN [proc[remote]] }; ServerValue: TYPE ~ REF ServerValueObject; ServerValueObject: TYPE ~ RECORD [ next: ServerValue, pgm: CARD32, pgmLoVersion: CARD16, pgmHiVersion: CARD16, serverProc: CrRPC.ServerProc, stopServerQueryProc: CrRPC.StopServerQueryProc]; serverTableSize: CARDINAL ~ 101; -- a modest prime ServerTable: TYPE ~ REF ServerTableObject; ServerTableObject: TYPE ~ RECORD [ values: ARRAY [0..serverTableSize) OF ServerValue]; serverTable: ServerTable ¬ NEW[ServerTableObject ¬ [ALL[NIL]]]; HashServer: INTERNAL PROC [pgm: CARD32] RETURNS[index: CARD] ~ INLINE { index ¬ pgm MOD CARD[serverTableSize] }; FetchServerValue: INTERNAL PROC [pgm: CARD32, pgmVersion: CARD16] RETURNS [ServerValue] ~ { index: CARD ~ HashServer[pgm]; FOR p: ServerValue ¬ serverTable.values[index], p.next WHILE p # NIL DO IF (p.pgm = pgm) AND (p.pgmLoVersion <= pgmVersion) AND (p.pgmHiVersion >= pgmVersion) THEN RETURN [p]; ENDLOOP; RETURN [NIL]; }; RegisterServerProcs: PUBLIC ENTRY PROC [pgm: CARD32, pgmLoVersion: CARD16, pgmHiVersion: CARD16, serverProc: CrRPC.ServerProc, stopServerQueryProc: CrRPC.StopServerQueryProc] ~ { ENABLE UNWIND => NULL; index: CARD; index ¬ HashServer[pgm]; serverTable.values[index] ¬ NEW[ServerValueObject ¬ [next~serverTable.values[index], pgm~pgm, pgmLoVersion~pgmLoVersion, pgmHiVersion~pgmHiVersion, serverProc~serverProc, stopServerQueryProc~stopServerQueryProc]]; }; LookUpServerProcs: PUBLIC ENTRY PROC [pgm: CARD32, pgmVersion: CARD16] RETURNS [serverProc: CrRPC.ServerProc, stopServerQueryProc: CrRPC.StopServerQueryProc] ~ { serverValue: ServerValue ~ FetchServerValue[pgm, pgmVersion]; IF serverValue # NIL THEN RETURN [serverValue.serverProc, serverValue.stopServerQueryProc] ELSE RETURN [NIL, NIL]; }; StartInstanceProcValue: TYPE ~ REF StartInstanceProcValueObject; StartInstanceProcValueObject: TYPE ~ RECORD [ startInstance: CrRPCBackdoor.StartServerInstanceProc]; startInstanceProcTable: RefTab.Ref ¬ RefTab.Create[]; RegisterStartServerInstanceProc: PUBLIC PROC [ class: CrRPC.HandleClass, startServerInstanceProc: CrRPCBackdoor.StartServerInstanceProc] ~ { [] ¬ RefTab.Store[x~startInstanceProcTable, key~class, val~NEW[StartInstanceProcValueObject ¬ [startServerInstanceProc]]]; }; LookupStartServerInstanceProc: PROC [class: ATOM] RETURNS [CrRPCBackdoor.StartServerInstanceProc] ~ { found: BOOL; val: REF; [found, val] ¬ RefTab.Fetch[x~startInstanceProcTable, key~class]; IF found THEN RETURN [NARROW[val, StartInstanceProcValue].startInstance] ELSE RETURN [NIL]; }; StartServerInstance: PUBLIC PROC [ pgm: CARD32, pgmVersion: CARD16, class: CrRPC.HandleClass, local: CrRPC.RefAddress] ~ { proc: CrRPCBackdoor.StartServerInstanceProc ~ LookupStartServerInstanceProc[class]; IF proc = NIL THEN ERROR Error[NIL, unknownClass, NIL]; proc[pgm, pgmVersion, local]; }; GetSeqHWord: PUBLIC PROC [s: STREAM] RETURNS [seqHWord: CrRPC.SeqHWord] ~ { n: CARD16; nBytes, nBytesRead: INT; n ¬ CrRPC.GetCard16[s]; seqHWord ¬ NEW[CrRPC.SeqHWordObject[n]]; nBytes ¬ (n*BITS[HWORD])/BITS[BYTE]; TRUSTED { nBytesRead ¬ IO.UnsafeGetBlock[self~s, block~[base~LOOPHOLE[seqHWord], startIndex~BITS[CrRPC.SeqHWordObject[0]]/BITS[BYTE], count~nBytes]] }; IF nBytesRead # nBytes THEN ERROR IO.EndOfStream[s] }; PutSeqHWORD: PUBLIC PROC [s: STREAM, seqHWord: CrRPC.SeqHWord] ~ { n: CARD16; nBytes: INT; n ¬ seqHWord.length; nBytes ¬ (n*BITS[HWORD])/BITS[BYTE]; CrRPC.PutCard16[s, n]; TRUSTED { IO.UnsafePutBlock[self~s, block~[base~LOOPHOLE[seqHWord], startIndex~BITS[CrRPC.SeqHWordObject[0]]/BITS[BYTE], count~nBytes]] }; }; GetSeqCard16: PUBLIC PROC [s: STREAM] RETURNS [seqCard16: CrRPC.SeqCard16] ~ { n: CARD16; nBytes, nBytesRead: INT; n ¬ CrRPC.GetCard16[s]; seqCard16 ¬ NEW[CrRPC.SeqCard16Object[n]]; nBytes ¬ (n*BITS[HWORD])/BITS[BYTE]; TRUSTED { nBytesRead ¬ IO.UnsafeGetBlock[self~s, block~[base~LOOPHOLE[seqCard16], startIndex~BITS[CrRPC.SeqCard16Object[0]]/BITS[BYTE], count~nBytes]] }; IF nBytesRead # nBytes THEN ERROR IO.EndOfStream[s]; IF NOT bigEndianHWords THEN FOR i: CARDINAL IN [0..n) DO seqCard16.body[i] ¬ Basics.Card16FromH[LOOPHOLE[seqCard16.body[i]]]; ENDLOOP; }; PutSeqCard16: PUBLIC PROC [s: STREAM, seqCard16: CrRPC.SeqCard16] ~ { n: CARD16; nBytes: INT; n ¬ seqCard16.length; nBytes ¬ (n*BITS[HWORD])/BITS[BYTE]; CrRPC.PutCard16[s, n]; IF NOT bigEndianHWords THEN FOR i: CARDINAL IN [0..n) DO seqCard16.body[i] ¬ LOOPHOLE[Basics.HFromCard16[seqCard16.body[i]]]; ENDLOOP; TRUSTED { IO.UnsafePutBlock[self~s, block~[base~LOOPHOLE[seqCard16], startIndex~BITS[CrRPC.SeqCard16Object[0]]/BITS[BYTE], count~nBytes]] }; }; SkipSeqHWord, SkipSeqCard16: PUBLIC PROC [s: STREAM] ~ { n: CARDINAL ~ CrRPC.GetCard16[s]; THROUGH [0 .. n) DO [] ¬ CrRPC.GetHWord[s]; ENDLOOP; }; GetRope: PUBLIC PROC [s: STREAM] RETURNS [rope: ROPE] ~ { len: CARDINAL ¬ CrRPC.GetCard16[s]; rope ¬ IO.GetRope[s, len, TRUE]; IF (len MOD 2) # 0 THEN [] ¬ IO.GetChar[s]; }; PutRope: PUBLIC PROC [s: STREAM, rope: ROPE] ~ { len: INT ~ Rope.Length[rope]; CrRPC.PutCard16[s, len]; IO.PutRope[s, rope]; IF (len MOD 2) # 0 THEN IO.PutChar[s, VAL[0]]; }; SkipROPE: PUBLIC PROC [h: Handle, s: STREAM] ~ { len: CARDINAL ¬ CrRPC.GetCard16[s]; IF (len MOD 2) # 0 THEN len ¬ len + 1; THROUGH [0 .. len) DO [] ¬ IO.GetChar[s]; ENDLOOP; }; MarshalledRopeHWords: PUBLIC PROC [rope: ROPE] RETURNS [hWords: CARDINAL] ~ { hWords ¬ (Rope.Length[rope] + 2*(BITS[HWORD]/BITS[BYTE]) - 1) / (BITS[HWORD]/BITS[BYTE]) }; GetBulkDataSource: PUBLIC PROC [h: Handle, s: STREAM] RETURNS [CrRPC.BulkDataSource] ~ { RETURN [h.procs.getBulkDataSource[h, s]] }; GetBulkDataSink: PUBLIC PROC [h: Handle, s: STREAM] RETURNS [CrRPC.BulkDataSink] ~ { RETURN [h.procs.getBulkDataSink[h, s]] }; finalizationQueue: FinalizeOps.CallQueue ¬ FinalizeOps.CreateCallQueue[ClientHandleFinalizer]; NewClientObject: PUBLIC PROC [class: CrRPC.HandleClass, procs: REF CrRPC.ProcsObject, data: REF ¬ NIL, clientData: REF ¬ NIL] RETURNS [h: Handle] ~ { h ¬ NEW[CrRPC.Object ¬ [class~class, kind~client, procs~procs, data~data, clientData~clientData]]; [] ¬ FinalizeOps.EnableFinalization[h, finalizationQueue]; }; ClientHandleFinalizer: FinalizeOps.FinalizeProc ~ { h: Handle ¬ NARROW[object]; IF h.procs.finalize # NIL THEN IF ( h.procs.finalize[h] ) THEN [] ¬ FinalizeOps.ReenableFinalization[handle]; }; }.  CrRPCImpl.mesa Copyright Σ 1986, 1990, 1991 by Xerox Corporation. All rights reserved. Demers, April 25, 1990 8:11 am PDT Willie-sue Orr, December 9, 1991 4:46 pm PST Michael Plass, April 16, 1990 9:43 am PDT Christian Jacobi, July 24, 1992 7:35 pm PDT Courier runtime support. Errors Create / Destroy for Client Handles N.B. This would need to be an ENTRY proc except that the RefTab package handles concurrent clients. N.B. This would need to be an ENTRY proc except that the RefTab package handles concurrent clients. Create / Destroy for Servers N.B. This would need to be an ENTRY proc except that the RefTab package handles concurrent clients. N.B. This would need to be an ENTRY proc except that the RefTab package handles concurrent clients. Marshalling Procs FinalizeOps Κ Ÿ–(cedarcode) style•NewlineDelimiter ™šœ™Icodešœ Οeœ=™HK™"K™,K™)K™+K™K™—K˜šΟk ˜ Kšœžœ žœ žœ˜6Kšœžœζ˜ρKšœžœ3˜FKšœ žœ^˜oKšžœžœ3žœ"˜cK˜)Kšœžœ žœ˜K˜—šΡbln œžœž˜Kšžœ)˜0Kšžœ˜Kšœ˜K˜Kšžœžœ žœ˜Kšžœžœ žœ˜Kšžœžœžœ˜Kšœžœ˜Kšžœžœžœžœ˜K˜KšœžœžœžœΟc˜Nhead™šΟnœžœžœ˜Kšœ ˜ Kšœ˜Kšœžœžœ˜——™#Kšœžœžœ#˜Jšœ#žœžœ˜2Kšœ?˜?K˜—˜:K˜—š‘œžœžœ žœ-˜fK™cKšœ˜Kšœ@žœ.˜qK˜K˜—š‘œžœ žœžœ+˜cK™cKšœžœ˜ Kšœžœ˜ K˜Fšžœ˜Kšžœžœžœ:˜MKšžœžœžœ˜—K˜K˜—š ‘œžœžœ žœžœ˜bKšœQ˜QKš žœžœžœžœžœžœ˜7Kšžœ˜Kšœ˜K˜——™Kšœ žœžœ˜*šœžœžœ˜"Kšœ˜Kšœžœ˜ Kšœžœ˜Kšœžœ˜Kšœ˜K˜0K˜—Kšœžœ ˜2Kšœ žœžœ˜*šœžœžœ˜"Kšœžœžœ˜3—šœžœžœžœ˜?K˜—š‘ œžœžœžœžœžœžœžœžœ˜pK˜—š ‘œžœžœžœžœžœ˜[Kšœžœ˜šžœ4žœžœž˜GKš žœžœ žœ žœžœ˜gKšžœ˜—Kšžœžœ˜ K˜K˜—š ‘œž œžœžœžœžœS˜²Kšžœžœžœ˜Kšœžœ˜ Kšœžœ˜KšœžœΆ˜ΥK˜K˜—š‘œžœžœžœžœžœžœS˜‘Kšœ=˜=šžœž˜Kšžœžœ:˜EKšžœžœžœžœ˜—K˜K˜—Kšœžœžœ˜@šœžœžœ˜-Kšœ6˜6K˜—˜5K˜—š‘œžœžœ˜.Kšœ˜Kšœ?˜?K™cKšœ˜Kšœ;žœ<˜zK˜K˜—š‘œžœ žœžœ,˜eK™cKšœžœ˜ Kšœžœ˜ K˜Ašžœ˜Kšžœžœžœ,˜?Kšžœžœžœ˜—K˜K˜—š ‘œžœžœžœžœ8˜zKšœS˜SKš žœžœžœžœžœžœ˜7Kšœ˜K˜——™š ‘ œžœžœžœžœ˜KKšœžœ˜ Kšœžœ˜K˜Kšœ žœ˜(Kš œ žœžœžœžœ˜$šžœ˜ Kš œ žœ$žœžœžœžœ˜—Kšžœžœžœžœ˜6K˜—š‘ œžœžœžœ˜BKšœžœ˜ Kšœžœ˜ K˜Kš œ žœžœžœžœ˜$K˜šžœ˜ Kš žœ$žœžœžœžœ˜€—K˜K˜—š ‘ œžœžœžœžœ!˜NKšœžœ˜ Kšœžœ˜K˜Kšœ žœ˜*Kš œ žœžœžœžœ˜$šžœ˜ Kš œ žœ$žœžœžœžœ˜—Kšžœžœžœžœ˜4š žœžœžœžœžœžœž˜8Kšœ'žœ˜DKšžœ˜—K˜K˜—š‘ œžœžœžœ!˜EKšœžœ˜ Kšœžœ˜ K˜Kš œ žœžœžœžœ˜$K˜š žœžœžœžœžœžœž˜8Kšœžœ(˜DKšžœ˜—šžœ˜ Kš žœ$žœžœžœžœ˜‚—K˜K˜—š ‘ œ‘ œžœžœžœ˜8Kšœžœ˜!šžœ ž˜K˜Kšžœ˜—K˜K˜—š ‘œž œžœžœžœ˜9Kšœžœ˜#Kšœžœžœ˜ Kšžœžœžœžœ ˜+Kšœ˜K˜—š‘œž œžœžœ˜0Kšœžœ˜Kšœ˜Kšžœ˜Kš žœžœžœžœ žœ˜.K˜K˜—š‘œž œžœ˜0Kšœžœ˜#Kšžœžœžœ˜&šžœ ž˜Kšœžœ ˜Kšžœ˜—K˜K˜—š ‘œž œžœžœ žœ˜MKšœ!žœžœžœžœ žœžœžœžœ˜[K˜—š ‘œžœžœžœžœ˜XKšžœ%˜+K˜—š ‘œžœžœžœžœ˜TKšžœ#˜)——™ K˜^K˜š‘œžœžœ#žœžœžœžœžœžœ˜•Kšœžœ[˜bK˜:K˜—K˜š‘œ˜3Kšœ žœ ˜šžœžœž˜Kšžœžœ/˜N—K˜K˜——K˜——…— Ό.q