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:
BOOL ←
FALSE] ~ {
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:
ROPE ←
NIL] ~ {
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:
BOOL ←
FALSE] ~ {
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:
BOOL ←
FALSE] ~ {
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];
};
}.