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