From 4e48d2724edafdebfe7fba4db01a50cd2a726d20 Mon Sep 17 00:00:00 2001 From: tomoya ishida Date: Fri, 5 Apr 2024 01:38:41 +0900 Subject: [ruby/reline] Thread safe readline (https://github.com/ruby/reline/pull/669) Block until other Reline.readline or Reline.readmultiline finish https://github.com/ruby/reline/commit/ebab2875f1 --- lib/reline.rb | 63 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'lib') diff --git a/lib/reline.rb b/lib/reline.rb index b1ff8fb56c..f0060f5c9c 100644 --- a/lib/reline.rb +++ b/lib/reline.rb @@ -75,6 +75,7 @@ module Reline def initialize self.output = STDOUT + @mutex = Mutex.new @dialog_proc_list = {} yield self @completion_quote_character = nil @@ -254,44 +255,48 @@ module Reline Reline::DEFAULT_DIALOG_CONTEXT = Array.new def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination) - unless confirm_multiline_termination - raise ArgumentError.new('#readmultiline needs block to confirm multiline termination') - end + @mutex.synchronize do + unless confirm_multiline_termination + raise ArgumentError.new('#readmultiline needs block to confirm multiline termination') + end - Reline.update_iogate - io_gate.with_raw_input do - inner_readline(prompt, add_hist, true, &confirm_multiline_termination) - end + Reline.update_iogate + io_gate.with_raw_input do + inner_readline(prompt, add_hist, true, &confirm_multiline_termination) + end - whole_buffer = line_editor.whole_buffer.dup - whole_buffer.taint if RUBY_VERSION < '2.7' - if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0 - Reline::HISTORY << whole_buffer - end + whole_buffer = line_editor.whole_buffer.dup + whole_buffer.taint if RUBY_VERSION < '2.7' + if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0 + Reline::HISTORY << whole_buffer + end - if line_editor.eof? - line_editor.reset_line - # Return nil if the input is aborted by C-d. - nil - else - whole_buffer + if line_editor.eof? + line_editor.reset_line + # Return nil if the input is aborted by C-d. + nil + else + whole_buffer + end end end def readline(prompt = '', add_hist = false) - Reline.update_iogate - io_gate.with_raw_input do - inner_readline(prompt, add_hist, false) - end + @mutex.synchronize do + Reline.update_iogate + io_gate.with_raw_input do + inner_readline(prompt, add_hist, false) + end - line = line_editor.line.dup - line.taint if RUBY_VERSION < '2.7' - if add_hist and line and line.chomp("\n").size > 0 - Reline::HISTORY << line.chomp("\n") - end + line = line_editor.line.dup + line.taint if RUBY_VERSION < '2.7' + if add_hist and line and line.chomp("\n").size > 0 + Reline::HISTORY << line.chomp("\n") + end - line_editor.reset_line if line_editor.line.nil? - line + line_editor.reset_line if line_editor.line.nil? + line + end end private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination) -- cgit v1.2.3