Skip to content

Commit 4f39744

Browse files
committed
Let's notify ide dispatcher after server started to avoid race described in #38
1 parent d13955e commit 4f39744

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

lib/ruby-debug-ide.rb

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
require 'stringio'
33
require "socket"
44
require 'thread'
5-
if (RUBY_VERSION < '2.0' || defined?(JRUBY_VERSION))
5+
if RUBY_VERSION < '2.0' || defined?(JRUBY_VERSION)
66
require 'ruby-debug-base'
77
else
88
require 'debase'
@@ -59,14 +59,14 @@ def interrupt_last
5959
end
6060
end
6161

62-
def start_server(host = nil, port = 1234)
62+
def start_server(host = nil, port = 1234, notify_dispatcher = false)
6363
return if started?
6464
start
65-
start_control(host, port)
65+
start_control(host, port, notify_dispatcher)
6666
end
6767

6868
def prepare_debugger(options)
69-
start_server(options.host, options.port)
69+
start_server(options.host, options.port, options.notify_dispatcher)
7070

7171
raise "Control thread did not start (#{@control_thread}}" unless @control_thread && @control_thread.alive?
7272

@@ -97,18 +97,20 @@ def run_prog_script
9797
end
9898
end
9999

100-
def start_control(host, port)
100+
def start_control(host, port, notify_dispatcher)
101101
raise "Debugger is not started" unless started?
102102
return if @control_thread
103103
@control_thread = DebugThread.new do
104104
begin
105105
# 127.0.0.1 seemingly works with all systems and with IPv6 as well.
106106
# "localhost" and nil have problems on some systems.
107107
host ||= '127.0.0.1'
108-
gem_name = (defined?(JRUBY_VERSION) || RUBY_VERSION < '1.9.0') ? 'ruby-debug-base' :
109-
RUBY_VERSION < '2.0.0' ? 'ruby-debug-base19x' : 'debase'
110108
server = TCPServer.new(host, port)
109+
gem_name = (defined?(JRUBY_VERSION) || RUBY_VERSION < '1.9.0') ? 'ruby-debug-base' :
110+
RUBY_VERSION < '2.0.0' ? 'ruby-debug-base19x' : 'debase'
111111
$stderr.printf "Fast Debugger (ruby-debug-ide #{IDE_VERSION}, #{gem_name} #{VERSION}) listens on #{host}:#{port}\n"
112+
notify_dispatcher(port) if notify_dispatcher
113+
112114
while (session = server.accept)
113115
$stderr.puts "Connected from #{session.peeraddr[2]}" if Debugger.cli_debug
114116
dispatcher = ENV['IDE_PROCESS_DISPATCHER']
@@ -134,6 +136,30 @@ def start_control(host, port)
134136
end
135137
end
136138

139+
private
140+
141+
def notify_dispatcher(port)
142+
return unless ENV['IDE_PROCESS_DISPATCHER']
143+
acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
144+
acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port
145+
146+
connected = false
147+
3.times do |i|
148+
begin
149+
s = TCPSocket.open(acceptor_host, acceptor_port)
150+
s.print(port)
151+
s.close
152+
connected = true
153+
return
154+
rescue => bt
155+
$stderr.puts "#{Process.pid}: connection failed(#{i+1})"
156+
$stderr.puts "Exception: #{bt}"
157+
$stderr.puts bt.backtrace.map { |l| "\t#{l}" }.join("\n")
158+
sleep 0.3
159+
end unless connected
160+
end
161+
end
162+
137163
end
138164

139165
class Exception # :nodoc:

lib/ruby-debug-ide/multiprocess/pre_child.rb

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,19 @@ def pre_child
1717
'stop' => false,
1818
'tracing' => false,
1919
'int_handler' => true,
20-
'cli_debug' => (ENV['DEBUGGER_CLI_DEBUG'] == 'true')
20+
'cli_debug' => (ENV['DEBUGGER_CLI_DEBUG'] == 'true'),
21+
'notify_dispatcher' => true
2122
)
2223

23-
acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
24-
acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port
25-
26-
connected = false
27-
3.times do |i|
28-
begin
29-
s = TCPSocket.open(acceptor_host, acceptor_port)
30-
s.print(port)
31-
s.close
32-
connected = true
33-
start_debugger(options)
34-
return
35-
rescue => bt
36-
$stderr.puts "#{Process.pid}: connection failed(#{i+1})"
37-
$stderr.puts "Exception: #{bt}"
38-
$stderr.puts bt.backtrace.map { |l| "\t#{l}" }.join("\n")
39-
sleep 0.3
40-
end unless connected
41-
end
24+
start_debugger(options)
4225
end
4326

4427
def start_debugger(options)
4528
if Debugger.started?
4629
# we're in forked child, only need to restart control thread
4730
Debugger.breakpoints.clear
4831
Debugger.control_thread = nil
49-
Debugger.start_control(options.host, options.port)
32+
Debugger.start_control(options.host, options.port, options.notify_dispatcher)
5033
end
5134

5235
if options.int_handler

0 commit comments

Comments
 (0)