-- StallWatcherImpl.mesa -- Russ Atkinson, November 1, 1982 3:54 pm DIRECTORY AMBridge USING [TVToCardinal], BBAction USING [Action, ActionId, NextPendingAction, WaitForChange], Process USING [Detach], StallWatcher, ViewersStallNotifier USING [NotifyProcessStalled]; StallWatcherImpl: CEDAR PROGRAM IMPORTS AMBridge, BBAction, Process, ViewersStallNotifier EXPORTS StallWatcher SHARES ViewersStallNotifier = BEGIN OPEN StallWatcher; RegisterStallNotifier: PUBLIC PROC [p: StallNotifyProcType, data: REF _ NIL] = TRUSTED { -- this proc registers a notifier to be called whenever a process -- "stalls" due to a breakpoint or uncaught signal in BugBane -- each call to RegisterStallNotifier will fork a new watchdog -- process, so don't be greedy! Process.Detach[FORK StallWatchProcess[p, data]]; }; StallWatchProcess: PROC [p: StallNotifyProcType, data: REF] = { -- this proc watches the world to find all stalled processes -- whenever there is a change, the current list is reported to the user -- by calling p[list,data] count: INT _ 0; lastId: BBAction.ActionId _ 0; DO maxId: BBAction.ActionId _ lastId; count _ BBAction.WaitForChange[count]; -- second, add new pending actions to the list FOR act: BBAction.Action _ BBAction.NextPendingAction[NIL], BBAction.NextPendingAction[act] WHILE act # NIL DO IF act.id <= lastId THEN LOOP; IF act.kind # break AND act.kind # signal THEN LOOP; p[act, data]; IF act.id > maxId THEN maxId _ act.id; ENDLOOP; lastId _ maxId; ENDLOOP; }; CallOut: StallNotifyProcType = TRUSTED { psb: CARDINAL _ AMBridge.TVToCardinal[action.event.process]; ViewersStallNotifier.NotifyProcessStalled [LOOPHOLE[psb], -- CROCK! IF action.kind = break THEN $Break ELSE $Signal]; }; RegisterStallNotifier[CallOut, NIL]; END.