-- 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.