AlpTransactionImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last edited by
Kolling on August 12, 1983 11:34 am
Carl Hauser, June 18, 1986 10:54:56 am PDT
DIRECTORY
AlpineEnvironment
USING[CommitOrAbort, FileStore, LockFailure, LockOption, NeededAccess,
OperationFailure, Outcome, OwnerName, OwnerPropertySet,
OwnerPropertyValuePair, PageCount, TransID, TransactionPriority, UnknownType,
VolumeID, VolumeGroupID],
AlpineFile
USING[AccessFailed, LockFailed, OperationFailed, PossiblyDamaged,
StaticallyInvalid, Unknown],
AlpInstance
USING[Handle],
AlpTransaction
USING[Handle, Object, RequestedOutcome, BeforeFinishProc, AfterFinishProc, FinishInfos],
AlpPrivate
USING[NoticeUnboundInstance],
RPC
USING[CallFailed],
AlpineTransactionRpcControl,
AlpineVolumeRpcControl,
AlpineOwnerRpcControl;
AlpTransactionImpl: CEDAR PROGRAM
IMPORTS AF: AlpineFile, AlpPrivate, RPC, AlpineTransactionRpcControl, AlpineVolumeRpcControl, AlpineOwnerRpcControl
EXPORTS AlpTransaction =
BEGIN OPEN AE: AlpineEnvironment, AlpI: AlpInstance, AlpT: AlpTransaction;
in addition to the errors documented for the corresponding Alpine procedures, all of the procedures defined in this interface can also error RPC.CallFailed[RPC.CallFailure]. At the moment, Alpine ignores the transID and lock parameters for GetVolumeGroup, GetNextVolumeGroup, and GetEnclosingVolumeGroup.
Priority: TYPE = AlpineEnvironment.TransactionPriority;
Create: PUBLIC PROCEDURE
[instHandle: AlpI.Handle, createLocalWorker: BOOLEAN, priority: Priority ← normal]
RETURNS [handle: AlpT.Handle]
= TRUSTED BEGIN
RETURN[NEW[AlpT.Object ← [inst: instHandle, transID:
instHandle.trans.Create[instHandle.conversation, createLocalWorker, priority
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[instHandle]]]]];
END;
CreateWithTransID: PUBLIC PROCEDURE
[instHandle: AlpI.Handle, transID: AE.TransID, createLocalWorker: BOOLEAN, priority: Priority ← normal]
RETURNS [handle: AlpT.Handle]
= TRUSTED BEGIN
handle ← NEW[AlpT.Object ← [inst: instHandle, transID: transID]];
IF createLocalWorker THEN instHandle.trans.CreateWorker[instHandle.conversation, transID,
instHandle.fileStore, priority
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[instHandle]];
END;
CreateWorker: PUBLIC PROCEDURE
[handle: AlpT.Handle, coordinator: AE.FileStore, priority: Priority ← normal]
= TRUSTED BEGIN
handle.inst.trans.CreateWorker[handle.inst.conversation, handle.transID, coordinator, priority
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
Finish: PUBLIC PROCEDURE
[handle: AlpT.Handle, requestedOutcome: AlpT.RequestedOutcome, continue: BOOLEAN]
RETURNS[outcome: AE.Outcome]
= TRUSTED BEGIN
FOR l: AlpT.FinishInfos ← handle.finishInfos, l.rest WHILE l # NIL DO
IF l.first.beforeFinish # NIL THEN l.first.beforeFinish[handle, l.first.clientData, requestedOutcome, continue];
ENDLOOP;
[outcome, handle.transID] ← handle.inst.trans.Finish[handle.inst.conversation, handle.transID, requestedOutcome, continue
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
FOR l: AlpT.FinishInfos ← handle.finishInfos, l.rest WHILE l # NIL DO
IF l.first.afterFinish # NIL THEN l.first.afterFinish[handle, l.first.clientData, outcome];
ENDLOOP;
END;
RegisterInterest: PUBLIC PROC [handle: AlpT.Handle, clientData: REF ANYNIL, beforeFinish: AlpT.BeforeFinishProc ← NIL , afterFinish: AlpT.AfterFinishProc ← NIL] ~ {
handle.finishInfos ← CONS[[beforeFinish, afterFinish, clientData], handle.finishInfos];
};
AssertAlpineWheel: PUBLIC PROCEDURE
[handle: AlpT.Handle, enable: BOOLEAN]
= TRUSTED BEGIN
handle.inst.trans.AssertAlpineWheel[handle.inst.conversation, handle.transID, enable
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
GetVolumeGroup: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, lock: AE.LockOption]
RETURNS[volumes: LIST OF AE.VolumeID]
= TRUSTED BEGIN
RETURN[handle.inst.volume.GetGroup[handle.inst.conversation, handle.transID, volumeGroupID, lock
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]]];
END;
GetNextVolumeGroup: PUBLIC PROCEDURE
[handle: AlpT.Handle, previousGroup: AE.VolumeGroupID, lock: AE.LockOption]
RETURNS[volumeGroupID: AE.VolumeGroupID]
= TRUSTED BEGIN
RETURN[handle.inst.volume.GetNextGroup[handle.inst.conversation,
handle.transID, previousGroup, lock
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]]];
END;
GetEnclosingVolumeGroup: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeID: AE.VolumeID, lock: AE.LockOption]
RETURNS[volumeGroupID: AE.VolumeGroupID]
= TRUSTED BEGIN
RETURN[handle.inst.volume.GetEnclosingGroup[handle.inst.conversation, handle.transID, volumeID, lock
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]]];
END;
CreateOwner: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName, properties: LIST OF AE.OwnerPropertyValuePair, enforceTotalQuota: BOOLEAN]
RETURNS[spaceLeftOnVolumeGroup: AE.PageCount]
= TRUSTED BEGIN
RETURN[handle.inst.owner.Create[handle.inst.conversation, handle.transID, volumeGroupID, owner, properties, enforceTotalQuota
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]]];
END;
DestroyOwner: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName]
= TRUSTED BEGIN
handle.inst.owner.Destroy[handle.inst.conversation, handle.transID,
volumeGroupID, owner
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
ReadNextOwner: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, previousOwner: AE.OwnerName, desiredProperties: AE.OwnerPropertySet]
RETURNS[owner: AE.OwnerName, properties: LIST OF AE.OwnerPropertyValuePair]
= TRUSTED BEGIN
[owner, properties] ← handle.inst.owner.ReadNext[handle.inst.conversation,
handle.transID, volumeGroupID, previousOwner, desiredProperties
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
ReadOwnerProperties: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName, desiredProperties: AE.OwnerPropertySet]
RETURNS[properties: LIST OF AE.OwnerPropertyValuePair]
= TRUSTED BEGIN
RETURN[handle.inst.owner.ReadProperties[handle.inst.conversation,
handle.transID,
volumeGroupID, owner, desiredProperties
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]]];
END;
WriteOwnerProperties: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName, overCommitQuotasIfNeeded: BOOLEAN, properties: LIST OF AE.OwnerPropertyValuePair]
= TRUSTED BEGIN
handle.inst.owner.WriteProperties[handle.inst.conversation, handle.transID,
volumeGroupID, owner, properties, (NOT overCommitQuotasIfNeeded)
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
ReadOwnerDBProperties: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID]
RETURNS[nOwners, nEntriesUsed, nEntries: NAT, totalQuota, totalSpaceInUse, volumeGroupSize: AE.PageCount]
= TRUSTED BEGIN
[nOwners: nOwners, nEntriesUsed: nEntriesUsed, nEntries: nEntries,
totalQuota: totalQuota, totalSpaceInUse: totalSpaceInUse, volumeGroupSize:
volumeGroupSize] ← handle.inst.owner.ReadDBProperties[handle.inst.conversation,
handle.transID, volumeGroupID
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
ReorganizeOwnerDB: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, nEntries: NAT]
= TRUSTED BEGIN
handle.inst.owner.ReorganizeDB[handle.inst.conversation, handle.transID,
volumeGroupID, nEntries
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
UnlockOwnerDB: PUBLIC PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID]
= TRUSTED BEGIN
handle.inst.owner.Unlock[handle.inst.conversation, handle.transID,
volumeGroupID
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[handle.inst]];
END;
AccessFailed: PUBLIC ERROR [missingAccess: AE.NeededAccess] ← AF.AccessFailed;
LockFailed: PUBLIC ERROR [why: AE.LockFailure] ← AF.LockFailed;
OperationFailed: PUBLIC ERROR [why: AE.OperationFailure] ← AF.OperationFailed;
StaticallyInvalid: PUBLIC ERRORAF.StaticallyInvalid;
Unknown: PUBLIC ERROR [what: AE.UnknownType] ← AF.Unknown;
PossiblyDamaged: PUBLIC SIGNALLOOPHOLE[AF.PossiblyDamaged];
END.
Edit Log
Initial: Kolling: February 14, 1983 3:56 pm: package to aid clients, in conjunction with AlpInstance and AlpFile.