DIRECTORY CD USING [Design], CDIO USING [WriteDesign], CDViewer USING [DesignOf], Interminal USING [terminal], IO USING [PutFR, int], MBQueue USING [Flush], Process USING [Detach, MsecToTicks, Pause, SecondsToTicks, SetPriority, priorityForeground], Rope USING [ROPE, Cat, IsEmpty], RuntimeError USING [UNCAUGHT], Terminal USING [GetKeys], TerminalIO USING [WriteRope], ViewerClasses USING [ViewerClass, SaveProc], ViewerOps USING [FetchViewerClass, EnumerateViewers, EnumProc]; CDEmergencyHandling: CEDAR MONITOR IMPORTS CDIO, CDViewer, Interminal, IO, MBQueue, Process, Rope, RuntimeError, Terminal, TerminalIO, ViewerOps = BEGIN SaveAll: PROC [] = BEGIN CallTheSaver: ViewerOps.EnumProc -- PROC [v: Viewer] RETURNS [BOOL _ TRUE] -- = BEGIN design: CD.Design = CDViewer.DesignOf[v].design; -- is not monitored IF design#NIL THEN Save[v, TRUE] END; ViewerOps.EnumerateViewers[CallTheSaver] END; EmergencySaveProcess: PROC = BEGIN Process.SetPriority[Process.priorityForeground]; DO -- forever Process.Pause[Process.SecondsToTicks[1]]; IF Interminal.terminal.GetKeys[][Spare3]=down AND Interminal.terminal.GetKeys[][RightShift]=down AND Interminal.terminal.GetKeys[][LeftShift]=down THEN SaveAll[] ENDLOOP; END; Save: ViewerClasses.SaveProc --PROC [self: Viewer, force: BOOL _ FALSE]-- = BEGIN IF force AND ~self.saveInProgress THEN { design: CD.Design = CDViewer.DesignOf[self].design; -- is not monitored IF design#NIL THEN { TRUSTED {Process.Detach[FORK MBQueue.Flush[design.queue]]}; TRUSTED {Process.Detach[FORK SaveDesign[design]]}; } } END; SaveDesign: PROC[design: CD.Design] = BEGIN done: BOOL _ FALSE; saveOn: Rope.ROPE; --using our own monitor prevents it at least from wedging together with other's; ReallySaveDesign: ENTRY PROC[design: CD.Design] = BEGIN ENABLE BEGIN UNWIND => NULL; RuntimeError.UNCAUGHT => GOTO next; END; FOR list: LIST OF CD.Design _ savedDesigns, list.rest WHILE list#NIL DO IF list.first=design THEN RETURN; ENDLOOP; saveOn _ IO.PutFR["///temp/chipndale/emergencysave%01g.dale", IO.int[saveKey^]]; saveKey^ _ saveKey^+1; done _ CDIO.WriteDesign[design: design, to: saveOn, emergency: TRUE]; IF done THEN savedDesigns _ CONS[design, savedDesigns]; EXITS next => NULL END; Process.Pause[Process.MsecToTicks[100]]; -- give the detached Flush process a chance ReallySaveDesign[design]; IF done THEN TerminalIO.WriteRope[Rope.Cat["design ", (IF Rope.IsEmpty[design.name] THEN "no name" ELSE design.name), " emergency saved on file """, saveOn, """\nWARNING: This write was made out of synchronisation; (what means: if any other process was fooling with the design, both could be broken, the design, and the file). Roll back, Copy the file and CHECK it.\n"]]; END; savedDesigns: LIST OF CD.Design _ NIL; saveKey: REF INT = NEW[INT_0]; -- ref used as key; referent used as counter class: ViewerClasses.ViewerClass = ViewerOps.FetchViewerClass[$Chipndale]; IF class#NIL AND class.save=NIL THEN class.save _ Save; TRUSTED {Process.Detach[FORK EmergencySaveProcess[]]}; END. :CDEmergencyHandling.mesa by Christian Jacobi July 13, 1984 9:11:20 am PDT last edited Christian Jacobi July 13, 1984 9:11:25 am PDT --typically called from a debugger --I checked the implementation; --ViewerOps.EnumerateViewers then was really not monitored -- -- -- -- -- -- -- -- -- -- -- -- now real stuff --otherwise don't consider saving --vanilla try to avoid concurrency with the write, which is unmonitored; --forked, so save may not hang in MBQueue monitor locking on the design --forked, so save of other designs may not hang --we must use some monitor because emergencywrite tries to kill any interferences, --which could be other emergencywrite's --we use the list business to prevent multiple save instead of CDValue, --to never call any monitored procedure which could cause additional wedges ʈ˜J˜Jšœ™Jšœ3™3Jšœ;™;J˜šÏk ˜ Jšœœ ˜Jšœœ˜Jšœ œ ˜Jšœ œ ˜Jšœœ˜Jšœœ ˜JšœœO˜\Jšœœœ˜ Jšœ œœ˜Jšœ œ ˜Jšœ œ ˜Jšœœ˜,Jšœ œ0˜?J˜—šÏbœœ˜"Jšœœd˜p—Jš˜J˜šÏnœœ˜Jšœ"™"Jš˜J˜šž œÏc,œ˜OJš˜Jšœœ( ˜EJšœœœ œ˜ Jšœ˜—J™Jšœ ™ Jšœ:™:Jšœ(˜(Jšœ˜—J˜šŸœœ˜Jš˜Jšœ0˜0šœ  ˜ J˜)šœ+˜-Jšœ/˜2Jšœ.˜1Jšœ ˜—Jšœ˜—Jšœ˜J˜—J˜Jšž!™!J™J™šžœ ,œ˜KJš˜šœœœ˜(Jšœ!™!Jšœœ, ˜Išœœœ˜J˜JšœH™HJšœG™GJšœœ!˜=J˜Jšœ/™/Jšœœ˜2J˜Jšœ˜—Jšœ˜—Jš˜—J˜šŸ œœ œ ˜%Jš˜Jšœœœ˜Jšœ œ˜J˜Jšœ N˜PJšœR™RJšœ(™(šŸœœœ œ ˜1Jš˜šœ˜ Jšœœ˜Jšœ œœ˜#Jšœ˜—J™JšœH™HJšœK™Kš œœœœ"œœ˜GJšœœœ˜!Jšœ˜—Jšœ œ3œ˜PJšœ˜Jšœœ4œ˜EJšœœœ˜7Jšœ ˜Jšœ˜—J˜Jšœ) +˜TJšœ˜šœœ*˜6Jšœœœ œ˜@Jšœ'˜'JšœÖ˜Ö—Jšœ˜—J˜J˜Jš œœœœ œ˜&Jš œ œœœœ -˜LJšœJ˜JJš œœœ œœ˜7Jšœœ˜6Jšœ˜J˜—…— Øš