How is the interrupt logic using primary+. working

If the image freezes, primary+. (ctrl/cmd+.)can be used to interrupt execution. The logic that is called to interrupt a running process is GlutinUserInterruptHandler>>#handleUserInterrupt handleUserInterrupt "This will be called from the event-fetcher process. Assume no system-vital processes have a lower priority than this, and are thus ok to interrupt" UserInterruptHandler cmdDotEnabled ifFalse: [ ^ self ]. [ self processToInterrupt ifNotNil: [ :aProcess | aProcess debugWithTitle: 'User Interrupt' ] ifNil: [ NonInteractiveTranscript stdout show: 'There is no process to interrupt'; cr ] "fork exceptions, we don't want interrupt handler to die" ] on: Error fork: [:ex | ex pass]. . This searches through the currently running processes for a process that can be interrupted using GlutinUserInterruptHandler>>#processToInterrupt processToInterrupt "Look for best candidate to interrupt: - any scheduled non-finalization process of lower priority - if the process has GlutinIgnoreDuringInterruptStatus set true the lookup searches for a better process. - the weak-finalization process, if scheduled - the UI process Never interrupt the idle process, since killing it is fatal" | fallback | "We use the UI process as a fallback in case no process is found." fallback := uiProcessBlock value. Processor scanSchedule: [ :aProcess | (self isAllowedToInterruptProcess: aProcess) ifTrue: [ (self canInterruptDirectly: aProcess ) ifTrue: [ ^ aProcess ] ifFalse: [ "Do not set any fallback here as we could end up interrupring a process that we skipped before and that we do not want to interrupt " ]]] startingAt: Processor activePriority. ^fallback .

One way to determine what process will be interrupted is using the snippet below

GlutinUserInterruptHandler new processToInterrupt
  

The interrupt shortcut is added by the current window host BlRustWindowingHost BlHost subclass: #BlRustWindowingHost instanceVariableNames: '' classVariableNames: '' package: 'BlocHost-Glutin-Host' as an event handler to the default event fetcher (RustWindowingEventFetcher Object subclass: #RustWindowingEventFetcher instanceVariableNames: 'eventHandlers fetcherProcess session' classVariableNames: 'default' package: 'Glutin-Event fetcher' ) in BlRustWindowingHost>>#start start PulseLoop start. RustWindowingEventFetcher default addEventHandler: UserInterruptEventHandler; addEventHandler: EventsSensor. RustWindowingEventFetcher install .

The event fetcher gets and executes events in a high priority process. This is needed as the current logic for locating processes to interrupt starts from the priority of the current active process.

If primary+. interrupts certain processes in the system there could be issues. To explicitly mark processes in a way that the interrupt logic will skip them we can use the process variable GlutinIgnoreDuringInterruptStatus ProcessLocalVariable subclass: #GlutinIgnoreDuringInterruptStatus instanceVariableNames: '' classVariableNames: '' package: 'Glutin-Event fetcher' .

This is currently used to ignore worker processes executing promises. Interrupting them could mean parts of the UI will stop working. We can skip them as they run at a lower priority than the UI and we can use the workers monitor to check their status.