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.