<> <> <> DIRECTORY Process USING [InitializeCondition, SecondsToTicks], Resource USING [AbortProc], Rope USING [ROPE]; ResourceImpl: CEDAR MONITOR IMPORTS Process EXPORTS Resource = BEGIN OPEN Resource; <> ownees: LIST OF Ownee _ NIL; Ownee: TYPE = RECORD[resource: REF ANY, owner: Rope.ROPE]; released: CONDITION; Acquire: PUBLIC ENTRY PROC [resource: REF ANY, waitForIt: BOOL _ FALSE, owner: Rope.ROPE _ NIL, abortProc: AbortProc _ NIL, <> abortProcData: REF ANY _ NIL ] RETURNS[success: BOOL, ownedBy: Rope.ROPE] = { ENABLE UNWIND => NULL; DO { FOR l: LIST OF Ownee _ ownees, l.rest UNTIL l = NIL DO IF l.first.resource = resource THEN IF waitForIt THEN { WAIT released; IF abortProc # NIL AND abortProc[abortProcData] THEN RETURN[FALSE, l.first.owner]; GOTO tryAgain} ELSE RETURN[FALSE, l.first.owner]; ENDLOOP; ownees _ CONS[[resource: resource, owner: owner], ownees]; RETURN[TRUE, owner]; EXITS tryAgain => LOOP; } ENDLOOP; }; Release: PUBLIC ENTRY PROC[resource: REF ANY] RETURNS[success: BOOL] = { ENABLE UNWIND => NULL; prev: LIST OF Ownee _ NIL; FOR l: LIST OF Ownee _ ownees, l.rest UNTIL l = NIL DO IF l.first.resource = resource THEN { IF prev = NIL THEN ownees _ l.rest ELSE prev.rest _ l.rest; BROADCAST released; RETURN[TRUE]} ELSE prev _ l; ENDLOOP; RETURN[FALSE]; }; IsAvailable: PUBLIC ENTRY PROC[resource: REF ANY] RETURNS[yes: BOOL, owner: Rope.ROPE] = { <> ENABLE UNWIND => NULL; FOR l: LIST OF Ownee _ ownees, l.rest UNTIL l = NIL DO IF l.first.resource = resource THEN RETURN[FALSE, l.first.owner]; ENDLOOP; RETURN[TRUE, NIL]; }; <> TRUSTED{Process.InitializeCondition[@released, Process.SecondsToTicks[1]]}; END.