@@ -59,25 +59,58 @@ def test_eval_evaluates_arithmetic_expressions
59
59
end
60
60
61
61
class EvaluateThreadTest < ProtocolTestCase
62
- PROGRAM = <<~RUBY
63
- 1| th0 = Thread.new{sleep}
64
- 2| m = Mutex.new; q = Queue.new
65
- 3| th1 = Thread.new do
66
- 4| m.lock; q << true
67
- 5| sleep 1
68
- 6| m.unlock
69
- 7| end
70
- 8| q.pop # wait for locking
71
- 9| p :ok
72
- RUBY
62
+ def test_eval_doesnt_deadlock
63
+ program = <<~RUBY
64
+ 1| th0 = Thread.new{sleep}
65
+ 2| m = Mutex.new; q = Queue.new
66
+ 3| th1 = Thread.new do
67
+ 4| m.lock; q << true
68
+ 5| sleep 1
69
+ 6| m.unlock
70
+ 7| end
71
+ 8| q.pop # wait for locking
72
+ 9| p :ok
73
+ RUBY
73
74
74
- def test_eval_with_threads
75
- run_protocol_scenario PROGRAM , cdp : false do
75
+ run_protocol_scenario program , cdp : false do
76
76
req_add_breakpoint 9
77
77
req_continue
78
78
assert_repl_result ( { value : 'false' , type : 'FalseClass' } , 'm.lock.nil?' , frame_idx : 0 )
79
79
req_continue
80
80
end
81
81
end
82
+
83
+ def test_eval_stops_threads_after_finished
84
+ program = <<~RUBY
85
+ 1| count = 0
86
+ 2| m = Thread::Mutex.new
87
+ 3| m.lock
88
+ 4|
89
+ 5| th0 = Thread.new do
90
+ 6| loop do
91
+ 7| m.synchronize do
92
+ 8| count += 1
93
+ 9| p :th0
94
+ 10| end
95
+ 11| end
96
+ 12| end
97
+ 13|
98
+ 14| __LINE__
99
+ RUBY
100
+
101
+ run_protocol_scenario program , cdp : false do
102
+ req_add_breakpoint 14
103
+ req_continue
104
+ assert_repl_result ( { value : '1' , type : 'Integer' } , '1' , frame_idx : 0 )
105
+ locals = gather_variables
106
+ count_var_value_1 = locals . find { |v | v [ :name ] == 'count' } [ :value ]
107
+ locals = gather_variables
108
+ count_var_value_2 = locals . find { |v | v [ :name ] == 'count' } [ :value ]
109
+ # if the thread is stopped, the value of count will not be changed.
110
+ assert_equal ( count_var_value_1 , count_var_value_2 )
111
+
112
+ req_continue
113
+ end
114
+ end
82
115
end
83
116
end
0 commit comments