From 1ba000856beff17aec3509b64e38a28eaa8d7d4f Mon Sep 17 00:00:00 2001
From: Stan Lo <stan001212@gmail.com>
Date: Wed, 29 Mar 2023 10:49:28 +0100
Subject: [PATCH] Restart threads on DAP evaluation

This makes sure DAP evaluation request also doesn't hang.

See #947 for the original console implementation.
---
 lib/debug/server_dap.rb    |  2 ++
 test/protocol/eval_test.rb | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/lib/debug/server_dap.rb b/lib/debug/server_dap.rb
index 829842866..bae1e4dda 100644
--- a/lib/debug/server_dap.rb
+++ b/lib/debug/server_dap.rb
@@ -625,6 +625,7 @@ def process_protocol_request req
           expr = req.dig('arguments', 'expression')
 
           if find_waiting_tc(tid)
+            restart_all_threads
             request_tc [:dap, :evaluate, req, fid, expr, context]
           else
             fail_response req
@@ -701,6 +702,7 @@ def process_protocol_result args
         register_vars result[:variables], tid
         @ui.respond req, result
       when :evaluate
+        stop_all_threads
         message = result.delete :message
         if message
           @ui.respond req, success: false, message: message
diff --git a/test/protocol/eval_test.rb b/test/protocol/eval_test.rb
index ee56a63e8..68add4e04 100644
--- a/test/protocol/eval_test.rb
+++ b/test/protocol/eval_test.rb
@@ -57,4 +57,27 @@ def test_eval_evaluates_arithmetic_expressions
       end
     end
   end
+
+  class EvaluateThreadTest < ProtocolTestCase
+    PROGRAM = <<~RUBY
+      1| th0 = Thread.new{sleep}
+      2| m = Mutex.new; q = Queue.new
+      3| th1 = Thread.new do
+      4|   m.lock; q << true
+      5|   sleep 1
+      6|   m.unlock
+      7| end
+      8| q.pop # wait for locking
+      9| p :ok
+    RUBY
+
+    def test_eval_with_threads
+      run_protocol_scenario PROGRAM, cdp: false do
+        req_add_breakpoint 9
+        req_continue
+        assert_repl_result({value: 'false', type: 'FalseClass'}, 'm.lock.nil?', frame_idx: 0)
+        req_continue
+      end
+    end
+  end
 end