-- AlpTransactionImpl.mesa
-- Last edited by
-- Kolling on August 12, 1983 11:34 am


DIRECTORY

AlpineEnvironment
USING[CommitOrAbort, FileStore, LockFailure, LockOption, NeededAccess,
OperationFailure, Outcome, OwnerName, OwnerPropertySet,
OwnerPropertyValuePair, PageCount, TransID, UnknownType, VolumeID,
VolumeGroupID],
AlpineFile
USING[AccessFailed, LockFailed, OperationFailed, PossiblyDamaged,
StaticallyInvalid, Unknown],
AlpInstance
USING[Handle],
AlpTransaction
USING[Handle, Object, RequestedOutcome],
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.


Create: PUBLIC PROCEDURE [instHandle: AlpI.Handle, createLocalWorker: BOOLEAN] RETURNS
[handle: AlpT.Handle] =
TRUSTED BEGIN
RETURN[NEW[AlpT.Object ← [inst: instHandle, transID:
instHandle.trans.Create[instHandle.conversation, createLocalWorker
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[instHandle]]]]];
END;

CreateWithTransID: PUBLIC PROCEDURE [instHandle: AlpI.Handle, transID: AE.TransID,
createLocalWorker: BOOLEAN] 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
! RPC.CallFailed => IF why = unbound OR why = timeout THEN
AlpPrivate.NoticeUnboundInstance[instHandle]];
END;


CreateWorker
: PUBLIC PROCEDURE[handle: AlpT.Handle, coordinator: AE.FileStore] =
TRUSTED BEGIN handle.inst.trans.CreateWorker[handle.inst.conversation, handle.transID,
coordinator
! 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 [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]];
END;

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 ERROR ← AF.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.