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],
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
ANY ←
NIL, 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 ERROR ← AF.StaticallyInvalid;
Unknown: PUBLIC ERROR [what: AE.UnknownType] ← AF.Unknown;
PossiblyDamaged: PUBLIC SIGNAL ← LOOPHOLE[AF.PossiblyDamaged];
Initial: Kolling: February 14, 1983 3:56 pm: package to aid clients, in conjunction with AlpInstance and AlpFile.