-- AlpInstanceImpl.mesa -- Last edited by -- Kolling on May 3, 1983 3:20 pm DIRECTORY AlpineEnvironment USING[Conversation, FileStore, LockFailure, NeededAccess, OperationFailure, Principal, UnknownType], AlpineFile USING[AccessFailed, Close, Create, Delete, GetAccessRights, GetFileID, GetLockOption, GetRecoveryOption, GetReferencePattern, GetSize, GetTransID, GetVolumeID, IncrementVersion, LockFailed, LockPages, Open, OperationFailed, PossiblyDamaged, ReadPages, ReadProperties, SetLockOption, SetReferencePattern, SetSize, StaticallyInvalid, UnlockPages, Unknown, UnlockVersion, WritePages, WriteProperties], AlpineFileRpcControl USING[ImportNewInterface, NewInterfaceRecord], AlpineOwner USING[AccessFailed, Create, Destroy, LockFailed, OperationFailed, ReadDBProperties, ReadNext, ReadProperties, ReorganizeDB, StaticallyInvalid, Unknown, WriteProperties], AlpineOwnerRpcControl USING[ImportNewInterface, NewInterfaceRecord], AlpineTransaction USING[AssertAlpineWheel, Create, CreateWorker, Finish, OperationFailed, Unknown], AlpineTransactionRpcControl USING[ImportNewInterface, NewInterfaceRecord], AlpineVolume USING[AccessFailed, GetEnclosingGroup, GetGroup, GetNextGroup, StaticallyInvalid, Unknown], AlpineVolumeRpcControl USING[ImportNewInterface, NewInterfaceRecord], AlpInstance USING[Failure, Handle, Object], AlpPrivate USING[InterfaceCreatorProc], ClientMap USING[Register], Rope USING[Equal, ROPE], RPC USING[AuthenticateFailed, CallFailed, EncryptionKey, GenerateConversation, GetCaller, ImportFailed, MakeKey, StartConversation, VersionRange], SafeStorage USING[GetSystemZone], UserCredentials USING[GetUserCredentials]; AlpInstanceImpl: MONITOR IMPORTS AE: AlpineEnvironment, AF: AlpineFile, AlpineFileRpcControl, AO: AlpineOwner, AlpineOwnerRpcControl, AT: AlpineTransaction, AlpineTransactionRpcControl, AV: AlpineVolume, AlpineVolumeRpcControl, AlpI: AlpInstance, ClientMap, Rope, RPC, SafeStorage, UserCredentials EXPORTS AlpInstance, AlpPrivate SHARES AlpineFileRpcControl, AlpineOwnerRpcControl, AlpineTransactionRpcControl, AlpineVolumeRpcControl = BEGIN objectCache: LIST OF AlpI.Object _ NIL; FindObjectInCache: INTERNAL PROCEDURE[fileStore: AE.FileStore, caller: AE.Principal, key: RPC.EncryptionKey, zone: ZONE] RETURNS[handle: AlpI.Handle] = BEGIN conversation: AE.Conversation; FOR list: LIST OF AlpI.Object _ objectCache, list.rest UNTIL list = NIL DO IF list.first.fileStore = fileStore THEN BEGIN conversation _ (IF Rope.Equal[RPC.GetCaller[list.first.conversation], caller, FALSE] THEN list.first.conversation ELSE RPC.StartConversation[caller, key, fileStore, authOnly]); handle _ zone.NEW[AlpI.Object _ [ trans: list.first.trans, file: list.first.file, owner: list.first.owner, volume: list.first.volume, otherInterfaces: list.first.otherInterfaces, conversation: conversation, fileStore: fileStore]]; RETURN; END; ENDLOOP; conversation _ RPC.StartConversation[caller, key, fileStore, authOnly]; handle _ zone.NEW[AlpI.Object _ [ trans: AlpineTransactionRpcControl.ImportNewInterface[[type: "AlpineTransaction.alpine", instance: fileStore, version: version], [NIL, NIL, NIL]], file: AlpineFileRpcControl.ImportNewInterface[[type: "AlpineFile.alpine", instance: fileStore, version: version], [NIL, NIL, NIL]], owner: AlpineOwnerRpcControl.ImportNewInterface[[type: "AlpineOwner.alpine", instance: fileStore, version: version], [NIL, NIL, NIL]], volume: AlpineVolumeRpcControl.ImportNewInterface[[type: "AlpineVolume.alpine", instance: fileStore, version: version], [NIL, NIL, NIL]], otherInterfaces: NIL, conversation: conversation, fileStore: fileStore]]; FOR list: LIST OF AlpPrivate.InterfaceCreatorProc _ interfaceCreators, list.rest UNTIL list = NIL DO handle.otherInterfaces _ CONS[list.first[fileStore, version], handle.otherInterfaces]; ENDLOOP; objectCache _ CONS[handle^, objectCache]; END; Create: PUBLIC ENTRY PROCEDURE[fileStore: AE.FileStore, caller: AE.Principal, key: RPC.EncryptionKey, zone: ZONE] RETURNS [handle: AlpI.Handle] = -- non system-fatal errors: -- Failed[authenticateFailed, other, unbound]. -- caller = NIL means the logged-in user. BEGIN ENABLE UNWIND => NULL; startedAlready _ TRUE; IF zone = NIL THEN zone _ SafeStorage.GetSystemZone[]; IF caller = NIL THEN BEGIN psw: Rope.ROPE; [caller, psw] _ UserCredentials.GetUserCredentials[]; key _ RPC.MakeKey[psw]; END; IF Rope.Equal[fileStore, "Local.alpine", FALSE] THEN BEGIN conversation: AE.Conversation _ RPC.GenerateConversation[ ! RPC.AuthenticateFailed => SELECT why FROM badCaller, badKey => GOTO noAuthenticate; ENDCASE => GOTO otherError]; ClientMap.Register[conversation, caller]; handle _ zone.NEW[AlpI.Object _ [ trans: AlpineTransactionRpcControl.NewInterfaceRecord[], file: AlpineFileRpcControl.NewInterfaceRecord[], owner: AlpineOwnerRpcControl.NewInterfaceRecord[], volume: AlpineVolumeRpcControl.NewInterfaceRecord[], otherInterfaces: NIL, conversation: conversation, fileStore: fileStore]]; handle.trans^ _ [Create: AT.Create, CreateWorker: AT.CreateWorker, AssertAlpineWheel: AT.AssertAlpineWheel, Finish: AT.Finish, Unknown: AT.Unknown, OperationFailed: AT.OperationFailed, lupineDetails: ]; handle.file^ _ [Open: AF.Open, Create: AF.Create, Close: AF.Close, Delete: AF.Delete, GetVolumeID: AF.GetVolumeID, GetFileID: AF.GetFileID, GetTransID: AF.GetTransID, GetAccessRights: AF.GetAccessRights, GetLockOption: AF.GetLockOption, SetLockOption: AF.SetLockOption, GetRecoveryOption: AF.GetRecoveryOption, GetReferencePattern: AF.GetReferencePattern, SetReferencePattern: AF.SetReferencePattern, ReadPages: AF.ReadPages, WritePages: AF.WritePages, LockPages: AF.LockPages, UnlockPages: AF.UnlockPages, ReadProperties: AF.ReadProperties, WriteProperties: AF.WriteProperties, UnlockVersion: AF.UnlockVersion, IncrementVersion: AF.IncrementVersion, GetSize: AF.GetSize, SetSize: AF.SetSize, AccessFailed: AF.AccessFailed, LockFailed: AF.LockFailed, OperationFailed: AF.OperationFailed, StaticallyInvalid: AF.StaticallyInvalid, Unknown: AF.Unknown, PossiblyDamaged: AF.PossiblyDamaged, lupineDetails: ]; handle.owner^ _ [ReadProperties: AO.ReadProperties, WriteProperties: AO.WriteProperties, Create: AO.Create, Destroy: AO.Destroy, ReadNext: AO.ReadNext, ReadDBProperties: AO.ReadDBProperties, ReorganizeDB: AO.ReorganizeDB, AccessFailed: AO.AccessFailed, LockFailed: AO.LockFailed, OperationFailed: AO.OperationFailed, StaticallyInvalid: AO.StaticallyInvalid, Unknown: AO.Unknown, lupineDetails: ]; handle.volume^ _ [GetNextGroup: AV.GetNextGroup, GetGroup: AV.GetGroup, GetEnclosingGroup: AV.GetEnclosingGroup, AccessFailed: AV.AccessFailed, Unknown: AV.Unknown, StaticallyInvalid: AV.StaticallyInvalid, lupineDetails: ]; FOR list: LIST OF AlpPrivate.InterfaceCreatorProc _ interfaceCreators, list.rest UNTIL list = NIL DO handle.otherInterfaces _ zone.CONS[list.first[fileStore, version], handle.otherInterfaces]; ENDLOOP; END ELSE handle _ FindObjectInCache[fileStore, caller, key, zone ! RPC.AuthenticateFailed => SELECT why FROM badCaller, badKey => GOTO noAuthenticate; ENDCASE => GOTO otherError; RPC.CallFailed => GOTO otherError; RPC.ImportFailed => SELECT why FROM badVersion, wrongVersion, unbound => GOTO unbound; ENDCASE => GOTO otherError;]; EXITS noAuthenticate => RETURN WITH ERROR Failed[authenticateFailed]; unbound => RETURN WITH ERROR Failed[unbound]; otherError => RETURN WITH ERROR Failed[other]; END; -- If a object in our cache has an InterfaceRecord matching an InterfaceRecord in this handle, throw out the object. I think one interface matching means all match..... NoticeUnboundInstance: PUBLIC ENTRY PROCEDURE[handle: AlpI.Handle] = -- non system-fatal errors: -- none. BEGIN prevEntry: LIST OF AlpI.Object _ NIL; list: LIST OF AlpI.Object _ objectCache; DO IF list = NIL THEN EXIT; IF list.first.trans = handle.trans THEN BEGIN IF prevEntry = NIL THEN objectCache _ list.rest ELSE prevEntry.rest _ list.rest; END ELSE prevEntry _ list; list _ list.rest; ENDLOOP; END; RegisterInterfaceCreator: PUBLIC ENTRY PROCEDURE[proc: AlpPrivate.InterfaceCreatorProc] = -- non system-fatal errors: -- none. BEGIN IF startedAlready THEN ERROR; interfaceCreators _ CONS[proc, interfaceCreators]; END; interfaceCreators: LIST OF AlpPrivate.InterfaceCreatorProc _ NIL; startedAlready: BOOLEAN _ FALSE; Failed: PUBLIC ERROR [why: AlpInstance.Failure] = CODE; version: RPC.VersionRange = [1, 1]; END. Edit Log Initial: Kolling: February 15, 1983 2:58 pm.