BridgeExecImpl.mesa
Demers, February 20, 1987 8:59:13 pm PST
DIRECTORY
BridgeExec USING [CreateProc, DestroyProc, Instance],
IO USING [STREAM],
Process USING [Detach],
RefTab USING [Create, Delete, EachPairAction, Fetch, Pairs, Ref, Store],
Rope USING [ROPE],
SymTab USING [Create, Delete, Fetch, Ref, Store];
BridgeExecImpl: CEDAR MONITOR
LOCKS session USING session: Session
IMPORTS Process, RefTab, SymTab
EXPORTS BridgeExec
~ {
OPEN BridgeExec;
NetworkStream: TYPE ~ IO.STREAM;
ROPE: TYPE ~ Rope.ROPE;
Command Registration
Registration: TYPE ~ REF RegistrationObject;
RegistrationObject: TYPE ~ RECORD [
name: ROPE,
createProc: CreateProc,
clientData: REF,
destroyProc: DestroyProc
];
registrationTab: SymTab.Ref ← SymTab.Create[];
Register: PUBLIC PROC [name: ROPE, createProc: CreateProc, clientData: REF, destroyProc: DestroyProc] ~ {
IF createProc = NIL
THEN {
[] ← SymTab.Delete[x~registrationTab, key~name] }
ELSE {
r: Registration ← NEW[RegistrationObject ← [name, createProc, clientData, destroyProc]];
[] ← SymTab.Store[x~registrationTab, key~name, val~r] };
};
GetRegistration: PROC [name: ROPE] RETURNS [registration: Registration] ~ {
val: REF;
[val~val] ← SymTab.Fetch[x~registrationTab, key~name];
registration ← NARROW[val];
};
Session Management
Session: TYPE ~ REF SessionObject;
SessionObject: PUBLIC TYPE ~ MONITORED RECORD [
name: ROPE,
locks: NAT ← 0,
unlocked: CONDITION,
dead: BOOLFALSE,
creationTab: RefTab.Ref
];
CreateSession: PUBLIC PROC [sessionName: ROPE] RETURNS [newSession: Session] ~ {
newSession ← NEW[SessionObject ← [name~sessionName, creationTab~RefTab.Create[]]];
};
DestroySession: PUBLIC PROC [session: Session] ~ {
TRUSTED {
Process.Detach[ FORK DestroySessionWorker[session] ] };
};
DestroySessionWorker: PROC [session: Session] ~ {
DestroyOne: RefTab.EachPairAction -- [key, val] RETURNS [quit] -- ~ {
DestroyInstance[session, NARROW[key], NIL];
RETURN [FALSE] };
KillSessionWhenUnlocked[session];
[] ← RefTab.Pairs[x~session.creationTab, action~DestroyOne];
};
KillSessionWhenUnlocked: ENTRY PROC [session: Session] ~ {
ENABLE UNWIND => NULL;
WHILE session.locks > 0 DO WAIT session.unlocked ENDLOOP;
session.dead ← TRUE;
};
LockSession: ENTRY PROC [session: Session]
RETURNS [ok: BOOL] ~ {
ENABLE UNWIND => NULL;
IF session.dead
THEN RETURN [FALSE]
ELSE { session.locks ← session.locks.SUCC; RETURN [TRUE] };
};
UnlockSession: ENTRY PROC [session: Session] ~ {
ENABLE UNWIND => NULL;
IF (session.locks ← session.locks.PRED) = 0 THEN
BROADCAST session.unlocked;
};
SessionNameFromSession: PUBLIC PROC [session: Session]
RETURNS [sessionName: ROPE] ~ { RETURN [session.name] };
SessionIsDead: PUBLIC ENTRY PROC [session: Session]
RETURNS [dead: BOOL] ~ {
ENABLE UNWIND => NULL;
RETURN [session.dead] };
Instance Management
Creation: TYPE ~ REF CreationObject;
CreationObject: TYPE ~ RECORD [
registration: Registration,
args: ROPE,
instance: Instance
];
CreateInstance: PUBLIC PROC [cmdName: ROPE, s: NetworkStream, args: ROPE, session: Session] RETURNS [instance: Instance ← NIL] ~ {
registration: Registration;
creation: Creation;
registration ← GetRegistration[cmdName];
IF registration = NIL THEN RETURN;
IF NOT LockSession[session] THEN RETURN;
instance ← registration.createProc[s, args, session, registration.clientData];
IF instance = NIL THEN { UnlockSession[session]; RETURN };
creation ← NEW[CreationObject ← [registration, args, instance]];
[] ← RefTab.Store[x~session.creationTab, key~instance, val~creation];
UnlockSession[session];
};
DestroyInstance: PUBLIC PROC [session: Session, instance: Instance, clientData: REF] ~ {
creation: Creation ← DeleteCreationFromSession[session, instance];
IF creation # NIL THEN creation.registration.destroyProc[instance, clientData];
creation.instance ← NIL; -- help break cycles for garbage collector
};
DeleteCreationFromSession: ENTRY PROC [session: Session, instance: Instance]
RETURNS [creation: Creation] ~ {
ENABLE UNWIND => NULL;
val: REF;
[val~val] ← RefTab.Fetch[x~session.creationTab, key~instance];
[] ← RefTab.Delete[x~session.creationTab, key~instance];
creation ← NARROW[val];
};
}...