-- LockInternal.mesa
-- Last edited by
-- MBrown on January 30, 1984 12:19:25 pm PST
DIRECTORY
AlpineEnvironment,
AlpineInternal,
BasicTime,
Lock;
LockInternal: DEFINITIONS = BEGIN
LockID: TYPE = Lock.LockID;
LockMode: TYPE = Lock.LockMode;
Handle: TYPE = REF Object;
HeaderHandle: TYPE = REF Object.header;
RequestHandle: TYPE = REF Object.request;
GrantedRequestHandle: TYPE = REF Object.request.granted;
WaitingRequestHandle: TYPE = REF Object.request.waiting;
LockTransHeaderHandle: TYPE = REF Object.request.transHeader;
ObjectType: TYPE = {header, request};
RequestObjectType: TYPE = {granted, waiting, transHeader};
Object: TYPE = RECORD [
requestList: Handle ← NIL,
-- circular list consisting of one Object.header, one or more Object.requests
--with granted or waiting variant.
body: SELECT type: ObjectType FROM
header => [
lockID: LockID ← TRASH,
next: HeaderHandle ← NIL -- link field for hash table package
],
request => [
trans: AlpineInternal.TransHandle,
transList: RequestHandle,
-- circular list consisting of one LockObject.request.transHeader, zero or more
--LockObject.request.granted, all with same value of trans.
-- all waiting requests are linked into a single list, through this field.
mode: LockMode,
rest: SELECT type: RequestObjectType FROM
granted => [
count: NAT
],
waiting => [
somethingChanged: CONDITION,
giveUp: BOOL ← FALSE,
whyGivingUp: WhyGivingUp ← TRASH, -- meaningful only if giveUp
isConversion: BOOL ← FALSE,
startTime: BasicTime.GMT
],
transHeader => [ -- requestList = NIL
nLocks: NAT
],
ENDCASE
],
ENDCASE
];
WhyGivingUp: TYPE = { abort, timeout };
GetInfo: PROC [
generalInfoProc: GeneralInfoProc ← NIL,
lockEnumProc: LockEnumProc ← NIL,
waitingRequestEnumProc: WaitingRequestEnumProc ← NIL,
waitingRequestEnumProc2: WaitingRequestEnumProc ← NIL];
-- Enters Lock monitor. If generalInfoProc # NIL, calls it with current values of
--its parameters. On return, if lockEnumProc # NIL, enumerates the locks calling
--lockEnumProc until it returns quit: TRUE or all locks have been enumerated. Then
--if waitingRequestEnumProc # NIL, enumerates the waiting requests in the same
--fashion. Then if waitingRequestEnumProc2 # NIL, enumerates the waiting requests
--again, in the same fashion. Finally returns, releasing the Lock monitor.
-- None of the proc parameters should not call into monitors that may be held
--while calling into the Lock monitor (including the Lock monitor itself).
GeneralInfoProc: TYPE = PROC [nLocks, nRequests, nSetCalls, nSetCallsWaited: INT];
LockEnumProc: TYPE = PROC [
h: HeaderHandle] RETURNS [stop: BOOL];
WaitingRequestEnumProc: TYPE = PROC [
wr: WaitingRequestHandle] RETURNS [stop: BOOL];
TimeoutWaitingRequest: PROC [wr: WaitingRequestHandle];
-- Cause the Lock.Set call to raise Lock.Failed[timeout].
END.