Skip to content

Commit

Permalink
more robust interrupt detection and terminate process
Browse files Browse the repository at this point in the history
  • Loading branch information
YO4 committed Nov 2, 2024
1 parent cc8beb0 commit dc6c49a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 6 deletions.
1 change: 1 addition & 0 deletions lib/yamatanooroti/windows/conhost.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def self.setup_console(height, width, wait, timeout, name)
attr_reader :console_process_id

def initialize(height, width, wait, timeout, name)
check_interrupt
@wait = wait
@timeout = timeout
@name = name
Expand Down
1 change: 1 addition & 0 deletions lib/yamatanooroti/windows/terminal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def get_size
end

def initialize(height, width, wait, timeout, title = "yamatanooroti")
check_interrupt
@wait = wait
@timeout = timeout
@result = nil
Expand Down
16 changes: 10 additions & 6 deletions lib/yamatanooroti/windows/windows-definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -521,22 +521,26 @@ def self.restore_console_control_handler(&block)
end
end

@interrupt_monitor_pid = spawn("ruby --disable=gems -e sleep #InterruptMonitor", [:out, :err] => "NUL")
@interrupt_monitor = Process.detach(@interrupt_monitor_pid)
@pipe = IO.pipe
@interrupt_catcher_pid = spawn("choice /m #InterruptCatcher", {:in => @pipe[0], [:out, :err] => "NUL"})
@interrupt_catcher = Process.detach(@interrupt_catcher_pid)
ignore_console_control_handler
@interrupted_p = nil
@pipe[0].close

def self.interrupted?
@interrupted_p ||
unless @interrupt_monitor.alive?
@interrupted_p = (@interrupt_monitor.value.exitstatus == 3)
unless @interrupt_catcher.alive?
@interrupted_p = (@interrupt_catcher.value.exitstatus == 0)
end
end

def self.at_exit
if @interrupt_monitor.alive?
@pipe[1].close unless @pipe[1].closed?
if @interrupt_catcher.alive?
sleep 0.01
begin
Process.kill("KILL", @interrupt_monitor_pid)
Process.kill("KILL", @interrupt_catcher_pid)
rescue Errno::ESRCH # No such process
end
end
Expand Down
3 changes: 3 additions & 0 deletions lib/yamatanooroti/windows/windows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def close
@target.close if close_request
@result = retrieve_screen if retrieve_request
@result ||= ""
check_interrupt
end

def clear_need_wait_flag
Expand Down Expand Up @@ -328,6 +329,8 @@ def check_interrupt
end

def raise_interrupt
@target&.close
close!
raise Interrupt, "Interrupt: Interrupt catcher process died."
end
end

0 comments on commit dc6c49a

Please sign in to comment.