<> <> <> <> DIRECTORY CrRPC USING [Handle, PutArgsProc], Rope USING [ROPE], CourierBinding USING [Address, Predicate, Range, Registration, RegistrationObject], CourierBindingProtocol USING [program, version, socket]; CourierBindingServerImpl: CEDAR MONITOR EXPORTS CourierBinding ~ { <> <<>> Address: TYPE ~ CourierBinding.Address; Handle: TYPE ~ CrRPC.Handle; Predicate: TYPE ~ CourierBinding.Predicate; PutArgsProc: TYPE ~ CrRPC.PutArgsProc; Range: TYPE ~ CourierBinding.Range; Registration: TYPE ~ CourierBinding.Registration; RegistrationObject: TYPE ~ CourierBinding.RegistrationObject; ROPE: TYPE ~ Rope.ROPE; <> <<>> RegistrationList: TYPE ~ LIST OF Registration; <> <<>> registered: RegistrationList; <> Intersect: PROC [a, b: Range]RETURNS [Range] ~ INLINE { RETURN[[MAX[a.lowVersion, b.lowVersion], MIN[a.highVersion, b.highVersion]]]; }; LegalRange: PROC [r: Range] RETURNS [BOOLEAN] ~ INLINE { RETURN[r.lowVersion <= r.highVersion]; }; <<>> <> Error: ERROR[r: ROPE] ~ CODE; RaiseError: PROC [r: ROPE] ~ { Error[r] }; <<>> <> Compare: PROC [i, j: Registration] RETURNS [x: {less, equal, greater}] ~ { SELECT TRUE FROM (i.program < j.program) => { RETURN [less]; }; (i.program = j.program) => { SELECT TRUE FROM (i.range.lowVersion < j.range.lowVersion) => { RETURN [less]; }; (i.range.lowVersion = j.range.lowVersion) => { <> SELECT TRUE FROM (i.range.highVersion < j.range.highVersion) => { RETURN [less]; }; (i.range.highVersion = j.range.highVersion) => { RETURN [equal]; }; ENDCASE => { RETURN [greater]; }; }; ENDCASE => { RETURN [greater]; }; }; ENDCASE => { RETURN [greater]; }; }; InsertInternal: INTERNAL PROC [n: Registration] ~ { g: RegistrationList; <> IF (registered = NIL) OR (Compare[n, registered.first] = greater) THEN { registered _ CONS[n, registered]; RETURN; }; <> FOR g _ registered, g.rest UNTIL (g.rest = NIL) DO SELECT Compare[g.rest.first, n] FROM less => { NULL; }; equal => { <> RaiseError["Abort to smash old Registration" ! ABORTED => { g.rest _ CONS[n, g.rest]; CONTINUE; } ]; }; ENDCASE => { g.rest _ CONS[n, g.rest]; }; ENDLOOP; <> g.rest _ CONS[n, NIL]; }; Locate: INTERNAL PROC [program: CARD, version: CARDINAL] ~ { }; RemoveInternal: INTERNAL PROC [n: Registration] ~ { g: RegistrationList; <> IF (registered = NIL) THEN ERROR; IF (Compare[n, registered.first] = equal) THEN { registered _ registered.rest; RETURN; }; <> FOR g _ registered, g.rest UNTIL (g.rest = NIL) DO SELECT Compare[g.rest.first, n] FROM less => { NULL; }; equal => { g _ g.rest; }; ENDCASE => { ERROR; -- not here! }; ENDLOOP; <> ERROR; }; <<>> <> Dispatcher: PROC [h: Handle, program: CARD, version: CARDINAL] ~ { }; Init: PROC ~ { <> <> }; <<>> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <<}>> <> <<};>> <<>> <> <> <> <> <> <<};>> <> <> <> <> <> <> <>> <> <>> <> <>> <> < {>> <> <> <<0,>> <> <<];>> <> <> <> <<};>> < Socket.ReturnBuffer[b];>> <> <<};>> <<>> <> <<>> <> < NULL;>> <<>> <> <> <> <> <<};>> <<>> <> <> <> <> <> <<>> <> <> < {argProblem _ TRUE; CONTINUE}];>> <> <> <> <> <> <<};>> <> < { exported _ [1, 0]; };>> <> <<};>> <<>> Register: PUBLIC ENTRY PROC [program: CARD, range: Range, predicate: Predicate, clientData: REF] RETURNS [r: Registration] ~ { ENABLE UNWIND => NULL; r _ NEW [RegistrationObject _ [clientData, predicate, program, range]]; InsertInternal[r]; }; UnRegister: PUBLIC ENTRY PROC [r: Registration] ~ { ENABLE UNWIND => NULL; RemoveInternal[r]; }; Init[]; }...