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.