XNSFilingSessionImpl.mesa
Copyright Ó 1990 by Xerox Corporation. All rights reserved.
Bill Jackson (bj), May 30, 1990 1:32 pm PDT
DIRECTORY
BasicTime USING [Now],
CrRPC USING [CreateClientHandle, DestroyClientHandle, Error, Handle],
FilingP10V5 USING [Handle, Session],
PFinalize USING [EnableFinalization, FinalizationQueue, FQEmpty, FQNext, Handle, HandleToObject, NewFQ],
PFS USING [Error],
Rope USING [ROPE],
RuntimeError USING [],
XNSAuth USING [Conversation, GetNextVerifier],
XNSFilingOps USING [CallProtected, ContinueOp, GuardOp, LogoffOp, LogonOp, MountRootOp, ServerData],
XNSFilingSession USING [ServerHandle, ServerObject];
XNSFilingSessionImpl: CEDAR MONITOR
IMPORTS BasicTime, CrRPC, PFinalize, PFS, XNSAuth, XNSFilingOps
EXPORTS XNSFilingSession ~ {
OPEN FilingP10V5, XNSFilingOps, XNSFilingSession;
ROPE: TYPE ~ Rope.ROPE;
Server Data Management
dfq: PFinalize.FinalizationQueue ~ PFinalize.NewFQ[--20--];
CollectLostHandles: PROC ~ {
Finalization ...
WHILE ( NOT PFinalize.FQEmpty[dfq] ) DO
handle: PFinalize.Handle ~ PFinalize.FQNext[dfq];
object: REF ~ PFinalize.HandleToObject[handle];
mnt: ServerData ~ NARROW[object];
ReleaseState: PROC ~ { LogoffOp[mnt] };
CallProtected[mnt, ReleaseState];
ENDLOOP;
};
Server Data Management
XNSSweepInner: ENTRY PROC [mnt: ServerData, seconds: CARD]
RETURNS [cleanUp: BOOLFALSE] ~ {
ENABLE UNWIND => NULL;
SELECT TRUE FROM
( mnt.admin.trTTL > seconds ) => { mnt.admin.trTTL ← mnt.admin.trTTL - seconds };
( NOT mnt.admin.active ) => { mnt.admin.trTTL ← 0; cleanUp ← TRUE };
there is no time left on the connection so kill it.
ENDCASE => { NULL };
};
XNSSweep: PUBLIC PROC [h: ServerHandle, seconds: CARD] ~ {
mnt: ServerData ~ NARROW[h.mnt];
ReleaseState: PROC ~ { LogoffOp[mnt] };
cleanUp: BOOL ~ XNSSweepInner[mnt, seconds];
IF ( cleanUp ) THEN CallProtected[mnt, ReleaseState];
CollectLostHandles[];
};
Transport management
TransportProblem: TYPE ~ {serverInaccessible, connectionTimedOut};
ReportTransportError: PROC [problem: TransportProblem, sH: ServerHandle] ~ {
ERROR;
};
GetConnection: PROC [sH: ServerHandle] RETURNS [crH: CrRPC.Handle] ~ {
mnt: ServerData ~ NARROW[sH.mnt];
crH ← CrRPC.CreateClientHandle[$SPP, mnt.address
! CrRPC.Error => ReportTransportError[$serverInaccessible, sH] ];
IF ( NOT Revive[mnt, crH] ) THEN {
IF ( crH # NIL ) THEN CrRPC.DestroyClientHandle[crH ! CrRPC.Error => CONTINUE];
ReportTransportError[$connectionTimedOut, sH];
};
mnt.admin.active ← TRUE;
};
Parameters
initialConnectionTTL: CARD ← 8;
credentialsErrorTTL: CARD ← 30;
Communications Startup
BogusAddress: ERROR ~ CODE;
allHandles: LIST OF PFinalize.Handle ← NIL;
RememberObject: PROC [h: PFinalize.Handle] ~ {
};
EstablishConnection: PROC [server: ROPE] RETURNS [mnt: ServerData ← NIL] ~ {
MountFileSystem: PROC ~ { mnt ← LogonOp[server]; MountRootOp[mnt] };
hook: PFinalize.Handle;
GuardOp[MountFileSystem];
mnt.admin ← [tktTTL: 10000, trTTL: initialConnectionTTL, callsOut: 0, files: 0, lastOp: BasicTime.Now[], downMsg: NIL, active: FALSE];
hook ← PFinalize.EnableFinalization[mnt, dfq]; -- dropping handle!
RememberObject[hook];
};
XNSGetServer: PUBLIC PROC [server: ROPE]
RETURNS [h: ServerHandle ← NIL, downMsg: ROPENIL] ~ {
Returns [NIL, NIL] if server doesn't exist.
Returns [NIL, msg] if server exists but is down.
downMsg ← "can\'t connect";
{
mnt: ServerData ← EstablishConnection[server];
h ← NEW[ServerObject ← [
--flavor: myFlavor, name: server, procs: myServerProcs,-- mnt: mnt]];
downMsg ← NIL;
};
};
Keep Alive activities
XNSValidate: PUBLIC ENTRY PROC [h: ServerHandle]
RETURNS [obsolete: BOOL, downMsg: ROPE] ~ {
ENABLE UNWIND => NULL;
mnt: ServerData ~ NARROW[h.mnt];
IF ( mnt.admin.trTTL > 0 ) THEN [] ← ReviveInternal[mnt]; -- returns 0 on errors
RETURN [(mnt.admin.trTTL <= 0), NIL];
};
minStart: CARD ← 10; -- seconds to allow credentials to get down to
Revive: ENTRY PROC [mnt: ServerData, crH: CrRPC.Handle ← NIL]
RETURNS [ok: BOOLFALSE] ~ {
ENABLE UNWIND => NULL;
IF ( mnt.admin.trTTL < minStart ) THEN RETURN[ReviveInternal[mnt]];
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
mnt.admin.trTTL ← mnt.timeToLive;
RETURN[TRUE];
};
ReviveInternal: INTERNAL PROC [mnt: ServerData]
RETURNS [ok: BOOLFALSE] ~ {
ENABLE PFS.Error => { GOTO GiveUp };
PokeServer: PROC ~ { ContinueOp[mnt] };
CallProtected[mnt, PokeServer];
ok ← TRUE;
EXITS GiveUp => { NULL };
};
Initialization
Init: PROC = {
PFinalize.EstablishFinalization[type: CODE[ServerDataObject], npr: 0, fq: dfq];
};
Init[];
}.