DIRECTORY AMEvents USING[ EventProc ], AMTypes USING [ TV ], DebuggerFormat USING [ DebugParameter, ExternalStateVector, SwapInfo ], PrincOps USING[ StateVector ], WorldVM USING[ Address, World ]; AMEventsBackdoorExtra: DEFINITIONS = BEGIN World: TYPE = WorldVM.World; Address: TYPE = WorldVM.Address; DebugParameter: TYPE = DebuggerFormat.DebugParameter; EventProc: TYPE = AMEvents.EventProc; StateVector: TYPE = PrincOps.StateVector; ExternalStateVector: TYPE = DebuggerFormat.ExternalStateVector; TV: TYPE = AMTypes.TV; Actor: TYPE = REF ActorObject; ActorObject: TYPE = RECORD[ next: Actor, world: World, data: REF, -- data to be passed back to the event proc proc: EventProc, -- event notification handler users: INT _ 1, -- reference count on GetEvents/StopEvents running: BOOL _ TRUE, -- client is running listener: PROCESS _ NIL, -- if not NIL, the process looking at the client bootCount: INT _ 0, -- incremented when a client session ends level: CARDINAL _ 0, -- nesting level of client procedure calls swapInfo: DebuggerFormat.SwapInfo _ NULL, esvAddr: Address _ 0, esv: ExternalStateVector _ NULL, paramAddr: Address _ 0, param: DebugParameter _ NULL, stateAddr: Address _ 0, state: StateVector _ NULL ]; KillThisTurkey: ERROR; NotImplemented: ERROR; BreakNotFound: ERROR; SupressUncaughtAborted: BOOL; CrashOnRecursiveAppearance: BOOL; Informing: BOOL; Wsls: BOOL; Actors: Actor ; -- the list of event watchers LocalActor: Actor ; PSBIToTV: PROC [psbi: CARDINAL, world: World] RETURNS [p: TV]; END. &AMEventsBackdoorExtra.mesa: backdoor interactions with client Copyright c 1985 by Xerox Corporation. All rights reserved. Bob Hagmann, November 26, 1985 1:43:22 pm PST Management of event watchers ("Actor") for each world common fields the remainder is only for world-swap and teledebug clients the remainder is data for interfacing with client Locking for fields in an ActorObject: Immutable: a.world, a.data, a.proc. Inside monitor: a.next, a.users, a.running, a.listener, a.bootCount By claiming "running": a.swapInfo, a.esvAddr, a.esv, a.paramAddr, a.param, a.stateAddr, a.state "a.level" is altered with the monitor and a.running claimed, so it may be read either inside the monitor or by claiming a.running. There are three sources of synchronisation problems: * ensuring that only one process transfers control to the client at a time * the client booting * someone calling "StopEvents" The a.running field provides mutual exclusion on transferring to the client. The a.bootCount field indicates when the client has booted. This is notified to the public through the BootedNotifiers. Having a.users=0 indicates a desire to disconnect from the client. This is notified to the BootedNotifiers and by aborting a.listener. Note that we never access the client with our monitor locked: local events require access to our monitor, but access to a remote client involves unbounded delays. Some low level errors Some control variables This is TRUE to kill off processes that do not have a base frame that catches ABORTED and flush out the process. This makes it easier to kill off processes. You can set this FALSE to find processes that are being aborted when you don't think that they are. RRA: We can set this to TRUE to carsh when a signal appears to be recursive. Experience has shown that signals appear to be recursive more often than they are recursive, however. Whether to raise the informational signals. You have to remember that ANY handles informational signals, so you probably want to use RuntimeError.UNCAUGHT to handle errors that others will not handle. If TRUE, will world-swap uncaught local signals, instead of sending them to the registered handler. This is useful before the handler is established, or when the handler is buggy. Bob Hagmann November 26, 1985 1:42:40 pm PST created interface Κ°˜codešœ=™=Kšœ Οmœ1™K˜Kšžœ˜K™—K™™,Kšœ™—K™K™K™K™K™K™—…—ψΞ