TerminalLocation.Mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on March 18, 1992 8:02 am PST
DIRECTORY
Basics USING [PartialComparison],
BasicTime USING [GMT],
IO USING [STREAM],
NetAddressing USING [Address],
RefTab USING [Ref],
Rope USING [ROPE];
TerminalLocation:
CEDAR
DEFINITIONS = {
A terminal has a set of locations. Output goes to all of them. One of the locations is designated the Primary one; input is taken only from the Primary location.
ROPE: TYPE ~ Rope.ROPE;
Location:
TYPE ~
RECORD [variant:
SELECT kind: Kind
FROM
undefined => [],
local => [],
remote => [addr: NetAddressing.Address],
ENDCASE];
Kind: TYPE ~ {undefined, local, remote};
RemoteLocation: TYPE ~ Location.remote;
LocsEqual: PROC [a, b: Location] RETURNS [BOOL]; --shallow
LocEquiv: PROC [a, b: Location] RETURNS [BOOL]; --deep
FormatLoc: PROC [Location] RETURNS [ROPE];
ParseLoc: PROC [ROPE] RETURNS [Location]; --May raise NA.Error.
HashLoc: PROC [Location] RETURNS [CARDINAL];
Canonicalize:
PROC [Location]
RETURNS [Location];
Two un-canonicalized RemoteLocations might be unequal due to aliases.
CanonicalHashLoc:
PROC [Location]
RETURNS [
CARDINAL];
A hash function that produces the same result for all equivalent inputs.
LocSet:
TYPE ~ RefTab.Ref;
Immutable. Keys are REF Locations; values are up to the client (which is the impl of this interface in the case of the LocSets in a LocState). A shallow LocSet tests NetAddressing.EqualAddrs; a deep one effectively applies NetAddressing.Canonicalize first.
CreateLocSet: PROC [shallow: BOOL] RETURNS [LocSet];
CopyLocSet:
PROC [LocSet]
RETURNS [LocSet];
Caller may mutate the result before handing it off as an official LocSet.
LocSetEqual: PROC [a, b: LocSet] RETURNS [BOOL];
LocSetCompare:
PROC [a, b: LocSet]
RETURNS [Basics.PartialComparison];
`less' means `proper subset'.
No guarantees if one set is shallow and the other deep.
LocState:
TYPE ~
RECORD [
primaryCancl, primaryPretty: Location,
allCancl, allPretty: LocSet
];
The *Cancl are the canonicalized versions of the *Pretty. The all* contain the primary and secondary locations; in particular, primaryPretty is in allPretty. Both LocSets are shallow, and the values associated with the keys therein are private to this interface's implementation. A LocState is immutable once created.
CreateSingleLocState:
PROC [cl, pl: Location]
RETURNS [LocState];
... where the primary location is the given one and there are no secondaries.
cl and pl are the canonical and pretty versions of the same location.
CopyLocState:
PROC [LocState]
RETURNS [LocState];
Begin creating a new LocState that differs from an existing one by some of the following steps.
LocStateSetPrimary:
PROC [ls: LocState, cl, pl: Location]
RETURNS [LocState];
ls's primary doesn't appear in result (unless it's the given location). The new primary may be an old secondary.
LocStateSelPrimary:
PROC [ls: LocState, cl, pl: Location]
RETURNS [LocState];
The former primary becomes a secondary.
LocStateEqual: PROC [a, b: LocState] RETURNS [BOOL];
LocStateIncrement:
PROC [ls: LocState, cl, pl: Location];
Adds the given location into the secondaries, if it's not already there.
LocStateDecrement:
PROC [LocState, Location];
Removes the given location, which must be canonical.
FormatLocState: PROC [LocState] RETURNS [ROPE];
FormatInstState: PROC [InstState] RETURNS [ROPE];
GetLocState:
PROC
RETURNS [LocState];
Will not return until the locations are definite.
PeekLoc:
PROC
RETURNS [InstState];
Returns ASAP.
InstState:
TYPE ~
RECORD [
SELECT kind: *
FROM
changing => [from, to: LocState],
stable => [state: LocState],
ENDCASE];
SetState:
PROC [LocState];
The following three procs are special cases, synchronized with state.
SetPrimary: PROC [l: Location];
SelPrimary: PROC [l: Location];
AddSecondary: PROC [Location];
Abandon:
PROC [old: Location, why: Why];
If the old is primary, a secondary is promoted to be primary, if possible.
Why: TYPE ~ RECORD [time: BasicTime.GMT, explanation: ROPE];
Wait: PROC [Test: PROC [LocState] RETURNS [done: BOOL ¬ TRUE]];
AllowObservers:
PROC [allow:
BOOL];
When allow=FALSE, incoming requests to observe are rejected (but locally initiated requests (via SetState and its special cases) are accepted).
ObserversAllowed:
PROC
RETURNS [
BOOL];
Returns current setting.
Client: TYPE ~ REF ClientPrivate;
ClientPrivate:
TYPE ~
RECORD [
NoteChange: PROC [Client, LocState] ¬,
data: REF ANY ¬ NIL];
AddClient: PROC [Client];
StartCommand:
PROC [in, out:
IO.
STREAM, cmd:
CHAR, postfixSelf:
BOOL]
RETURNS [ctlVersion:
NAT, err:
ROPE ¬
NIL];
I/O errors shine through.
}.