-- TiogaTouchupImpl.mesa, last edit by Paxton on June 17, 1983 1:36 pm
Last Edited by: Maxwell, January 6, 1983 11:38 am
DIRECTORY
TiogaTouchup,
Process USING [Ticks, MsecToTicks, SetTimeout],
Rope USING [ROPE],
TiogaDocument USING [SpinAndLock, TiogaDocumentData, Unlock],
TiogaNode USING [RefBranchNode],
TiogaLocks USING [Lock, LockRef, Unlock, WaitingForWrite];
TiogaTouchupImpl: CEDAR MONITOR
IMPORTS TiogaDocument, TiogaLocks, Process
EXPORTS TiogaTouchup = BEGIN
fullUpdate: PUBLIC REF ANY ← $Update;
refresh: PUBLIC REF ANY ← $Refresh;
RefreshOver:
PUBLIC
ENTRY
PROC = {
ENABLE
UNWIND =>
NULL;
BROADCAST refreshOver };
LockAfterScroll:
PUBLIC
PROC [tdd: TiogaDocument.TiogaDocumentData, who: Rope.
ROPE]
RETURNS [ok: BOOL] = { RETURN [LockAfter[tdd, who, TRUE]] };
LockAfterRefresh:
PUBLIC
PROC [tdd: TiogaDocument.TiogaDocumentData, who: Rope.
ROPE]
RETURNS [ok: BOOL] = { RETURN [LockAfter[tdd, who, FALSE]] };
LockAfter:
PROC [tdd: TiogaDocument.TiogaDocumentData, who: Rope.
ROPE, scroll:
BOOL]
RETURNS [ok: BOOL] = {
lock: TiogaLocks.LockRef;
doc: TiogaNode.RefBranchNode;
WaitForRefresh:
ENTRY
PROC
RETURNS [
BOOL] = {
ENABLE
UNWIND =>
NULL;
If scroll, then wait for ~tdd.dirty and tdd.scroll=no which means have done scroll.
count: NAT ← 0;
WHILE tdd.dirty
AND (~scroll
OR tdd.scroll=no)
DO
-- wait for refresh to finish
IF (count ← count+1) > 5 THEN RETURN [FALSE]; -- don't wait more than 5 seconds
IF TiogaLocks.WaitingForWrite[lock]
THEN
RETURN [
FALSE];
-- change of plans
Refresh will not complete because of pending edit. Must release read lock so edit can take place.
IF tdd.invisible
THEN
RETURN [
FALSE];
Never will be refreshed.
WAIT refreshOver; -- let refresh complete first
ENDLOOP;
RETURN [TRUE] };
[] ← TiogaDocument.SpinAndLock[tdd, "LockAfterRefresh1"]; -- lock it before read tdd.text
doc ← tdd.text;
TiogaDocument.Unlock[tdd]; -- need to unlock it again so refresh can take place while we wait
IF doc=NIL THEN RETURN [FALSE]; -- hasn't been initialized?
lock ← TiogaLocks.Lock[doc, who, read];
must do this before acquire monitor lock
IF ~WaitForRefresh[] THEN { TiogaLocks.Unlock[doc]; RETURN [FALSE] };
[] ← TiogaDocument.SpinAndLock[tdd, "LockAfterRefresh2"];
IF tdd.text # doc
THEN {
-- it changed while we had tdd unlocked
TiogaLocks.Unlock[doc]; TiogaDocument.Unlock[tdd]; RETURN [FALSE] };
RETURN [TRUE];
};
UnlockAfterRefresh:
PUBLIC PROC [tdd: TiogaDocument.TiogaDocumentData] = {
IF tdd.text#NIL THEN TiogaLocks.Unlock[tdd.text]; TiogaDocument.Unlock[tdd] };
refreshOver: CONDITION;
aLittleWhile: Process.Ticks = Process.MsecToTicks[1000];
TRUSTED {Process.SetTimeout[@refreshOver, aLittleWhile]}; -- recheck for refresh over every second
END.