LocalRegistryAgentImpl.mesa
Copyright Ó 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Spreitze, May 27, 1992 7:41 am PDT
Willie-s, August 21, 1991 1:05 pm PDT
Michael Plass, September 27, 1991 1:48 pm PDT
Chauser, January 3, 1992 11:21 am PST
DIRECTORY Arpa, Atom, Basics, BasicTime, Convert, IO, LocalRegistry, LocalRegistryAgent, LocalRegistryAgentBackdoor, LocalRegistryClient, Process, SimpleFeedback, SunPMap, SunPMapClient, SunRPC, SunRPCOnUDP, SunRPCAuth, ThisMachine;
LocalRegistryAgentImpl: CEDAR MONITOR
IMPORTS Basics, BasicTime, Convert, IO, LocalRegistry, LocalRegistryClient, Process, SimpleFeedback, SunPMapClient, SunRPC, SunRPCOnUDP, SunRPCAuth, ThisMachine
EXPORTS LocalRegistryAgent, LocalRegistryAgentBackdoor
= BEGIN OPEN LocalRegistryAgent;
ServiceRegistration: TYPE ~ REF ServiceRegistrationPrivate;
ServiceRegistrationPrivate: PUBLIC TYPE ~ RECORD [
name: ROPE,
value: PropList,
regTimeout, regPeriod: Milliseconds,
timer: CONDITION,
doer: PROCESS ¬ NIL,
newProps, started, stop, done: BOOL ¬ FALSE];
beVerbose: BOOL ¬ FALSE;
SetVerbosity: PUBLIC PROC [verbose: BOOL]
~ {beVerbose ¬ verbose; RETURN};
MaintainService: PUBLIC PROC [name: ROPE, value: PropList, regTimeout, regPeriod: Milliseconds] RETURNS [sr: ServiceRegistration] ~ {
sr ¬ NEW [ServiceRegistrationPrivate ¬ [name, value, regTimeout, regPeriod]];
TRUSTED {
Process.InitializeCondition[@sr.timer, Process.MsecToTicks[regPeriod]];
Process.EnableAborts[@sr.timer];
Process.Detach[sr.doer ¬ FORK Maintain[sr]]};
RETURN};
ChangeProps: PUBLIC PROC [sr: ServiceRegistration, newValue: PropList] ~ {
IF sr#NIL THEN EntryChangeProps[sr, newValue];
RETURN};
EntryChangeProps: ENTRY PROC [sr: ServiceRegistration, newValue: PropList] ~ {
ENABLE UNWIND => NULL;
sr.newProps ¬ TRUE;
sr.value ¬ newValue;
RETURN};
StopService: PUBLIC PROC [sr: ServiceRegistration] ~ {
IF sr#NIL THEN EnterAndStop[sr];
RETURN};
EnterAndStop: ENTRY PROC [sr: ServiceRegistration] ~ {
ENABLE UNWIND => NULL;
sr.stop ¬ TRUE;
NOTIFY sr.timer;
IF sr.started THEN UNTIL sr.done DO WAIT sr.timer ENDLOOP;
RETURN};
SetGoing: ENTRY PROC [sr: ServiceRegistration] RETURNS [go: BOOL] ~ {
ENABLE UNWIND => NULL;
IF sr.stop THEN RETURN [FALSE];
RETURN [sr.started ¬ TRUE]};
Wait: ENTRY PROC [sr: ServiceRegistration] RETURNS [go: BOOL] ~ {
ENABLE UNWIND => NULL;
WAIT sr.timer;
RETURN [NOT sr.stop]};
NoteGone: ENTRY PROC [sr: ServiceRegistration] ~ {
ENABLE UNWIND => NULL;
sr.done ¬ TRUE;
NOTIFY sr.timer;
RETURN};
Sample: ENTRY PROC [sr: ServiceRegistration] RETURNS [new: BOOL, props: PropList] ~ {
ENABLE UNWIND => NULL;
new ¬ sr.newProps;
props ¬ sr.value;
sr.newProps ¬ FALSE;
RETURN};
Maintain: PROC [sr: ServiceRegistration] ~ {
lrh, pmh: LocalRegistry.Handle ¬ NIL;
lrc, pmc: LocalRegistry.Conversation ¬ NIL;
lrPortNum: CARD;
lrPort: SunRPCOnUDP.Port;
sh: LocalRegistry.ServiceHandle ¬ ALL[0];
shValid: BOOL ¬ FALSE;
localAddressRope: ROPE;
localhost: Arpa.Address;
lastResult: LocalRegistry.ResultCode;
props: PropList ¬ sr.value;
new: BOOL ¬ FALSE;
CloseEm: PROC ~ {
IF lrh#NIL THEN SunRPC.Destroy[lrh !SunRPC.Error => CONTINUE];
lrh ¬ NIL;
IF lrc#NIL THEN SunRPCAuth.Terminate[lrc !SunRPC.Error, SunRPCAuth.Error => CONTINUE];
lrc ¬ NIL;
IF pmh#NIL THEN SunRPC.Destroy[pmh !SunRPC.Error => CONTINUE];
pmh ¬ NIL;
IF pmc#NIL THEN SunRPCAuth.Terminate[pmc !SunRPC.Error, SunRPCAuth.Error => CONTINUE];
pmc ¬ NIL;
RETURN};
Regit: PROC ~ {
IF lrh=NIL OR lrc=NIL THEN {
localAddressRope ¬ ThisMachine.Address[$Arpa];
localhost ¬ Convert.ArpaAddressFromRope[localAddressRope];
pmh ¬ SunRPCOnUDP.Create[localhost, Basics.HFromCard16[SunPMap.udpPort]];
pmc ¬ SunRPCAuth.Initiate[SunRPCAuth.nullFlavor];
lrPortNum ¬ SunPMapClient.GetPort[pmh, pmc, LocalRegistry.program, LocalRegistry.programVersion, SunPMap.ipProtocolUDP];
lrPort ¬ Basics.HFromCard16[lrPortNum];
lrh ¬ SunRPCOnUDP.Create[localhost, lrPort];
lrc ¬ SunRPCAuth.Initiate[SunRPCAuth.nullFlavor];
};
SELECT TRUE FROM
NOT shValid => lastResult ¬ otherFailure;
NOT new => lastResult ¬ LocalRegistryClient.Refresh[lrh, lrc, sh, sr.regTimeout];
ENDCASE => {
[] ¬ LocalRegistryClient.Refresh[lrh, lrc, sh, 0];
lastResult ¬ otherFailure};
IF lastResult#success THEN {
[lastResult, sh] ¬ LocalRegistryClient.Register[lrh, lrc, [name: sr.name, msToLive: sr.regTimeout, value: props], 0];
IF lastResult=success THEN shValid ¬ TRUE;
};
RETURN};
RegWithCatch: PROC RETURNS [err: BOOL] ~ {
NoteErr: PROC [fmt: ROPE, v1, v2, v3: IO.Value ¬ [null[]] ] ~ {
IF beVerbose THEN SimpleFeedback.PutFL[$LocalRegistry, oneLiner, $Error, "%g %g for %g in LocalRegistryAgentImpl", LIST[[time[BasicTime.Now[]]], [rope[IO.PutFR[fmt, v1, v2, v3]]], [rope[sr.name]]] ];
err ¬ TRUE;
RETURN};
err ¬ FALSE;
Regit[!
Convert.Error => {NoteErr["Convert.Error[%g, %g]", [atom[Convert.AtomFromErrorType[reason]]], [integer[index]] ]; CONTINUE};
LocalRegistry.Error => {NoteErr["LocalRegistry.Error" ]; CONTINUE};
SunRPC.Error => {NoteErr["SunRPC.Error[%g]", [atom[code]] ]; CONTINUE};
SunRPCAuth.Error => {NoteErr["SunRPCAuth.Error[%g]", [atom[code]] ]; CONTINUE}
];
IF err THEN CloseEm[];
RETURN};
IF SetGoing[sr] THEN {
DO
ENABLE UNWIND => NoteGone[sr];
[new, props] ¬ Sample[sr];
IF RegWithCatch[] THEN shValid ¬ FALSE;
IF NOT Wait[sr] THEN {
sr.regTimeout ¬ 0;
IF shValid THEN [] ¬ RegWithCatch[];
EXIT};
ENDLOOP;
NoteGone[sr];
CloseEm[];
};
RETURN};
END.