Skip to content

Commit 20389c3

Browse files
authored
Fix WinRM shell finalizer for Ruby 3.1+ by safely handling ThreadError (#354)
* fixing thread alloc error which comes after ruby 3.1 upgrade
1 parent 41e5e4c commit 20389c3

1 file changed

Lines changed: 29 additions & 1 deletion

File tree

lib/winrm/shells/base.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,36 @@ def close
9494
@shell_id = nil
9595
end
9696

97+
# Ruby 3.1+ introduced a change where finalizers cannot allocate new threads.
98+
# This can raise a ThreadError when the WinRM shell cleanup tries to run in a Thread
99+
# during garbage collection. Previously, the gem used Thread.new in finalizers.
100+
#
101+
# Our solution preserves original behavior safely:
102+
# 1. Attempt cleanup in a new thread (same as before) for normal execution.
103+
# 2. If a ThreadError occurs specifically due to "can't alloc thread",
104+
# defer cleanup to an at_exit block to ensure the shell is closed properly
105+
# without crashing the program.
106+
# 3. Any other ThreadError is re-raised to avoid hiding unexpected issues.
97107
def self.finalize(connection_opts, transport, shell_id)
98-
proc { Thread.new { close_shell(connection_opts, transport, shell_id) } }
108+
proc do
109+
begin
110+
# Attempt normal cleanup in a new thread (preserves existing behavior)
111+
Thread.new { close_shell(connection_opts, transport, shell_id) }
112+
rescue ThreadError => e
113+
# Only handle the specific Ruby 3.1+ GC thread allocation restriction
114+
raise unless e.message.include?("can't alloc thread")
115+
116+
# Defer cleanup to at_exit when thread allocation is permitted
117+
at_exit do
118+
begin
119+
close_shell(connection_opts, transport, shell_id)
120+
rescue StandardError => cleanup_error
121+
# Warn about cleanup failures in deferred context only
122+
warn "[WinRM] Deferred shell cleanup failed: #{cleanup_error.class}: #{cleanup_error.message}"
123+
end
124+
end
125+
end
126+
end
99127
end
100128

101129
protected

0 commit comments

Comments
 (0)