Project

General

Profile

Bug #15644

Updated by kke (Kimmo Lehto) 2 months ago

Using ThreadsWait with Thread.report_on_exception is confusing.

ThreadsWait
spawns a new thread for waiting on a thread:

```
# thwait.rb:87
def join_nowait(*threads)
threads.flatten!
@threads.concat threads
for th in threads
Thread.start(th) do |t|
begin
t.join
ensure
@wait_queue.push t
end
end
end
end
```

The `t.join` in `ThreadsWait` will re-raise As `thread.join` raises the exceptions that happen in exception from the thread, it will trigger a thread being waited on. exception report.

If the thread being waited on was using `report_on_exception = false`, the wait thread will report the exception and the `report_on_exception = false` effectively did nothing, as you still got an exception report.

anyway.

If the thread was using `report_on_exception = true`, both threads will report the exception, so you get it twice. exception.

I think this could be fixed by always setting `report_on_exception = false` for the wait thread.

# Example 1

```
require 'thwait'

thread = Thread.new do
Thread.current.report_on_exception = false
sleep 1
raise "Foo"
end

ThreadsWait.all_waits(thread) do |terminated_thread|
puts "Thread #{terminated_thread} terminated"
end
```

## Expected result

No exception reports

## Actual result

The wait thread will report the exception:

```
#<Thread:0x00007fa57d092d68@/Users/user/.rbenv/versions/2.6.1/lib/ruby/2.6.0/thwait.rb:91 run> terminated with exception (report_on_exception is true):
```

# Example 2

```
require 'thwait'

thread = Thread.new do
sleep 1
raise "Foo"
end

ThreadsWait.all_waits(thread) do |terminated_thread|
puts "Thread #{terminated_thread} terminated"
end
```

## Expected result

One exception report

## Actual result

Two exception reports:

```
#<Thread:0x00007f9f83053320@test.rb:3 run> terminated with exception (report_on_exception is true):
#<Thread:0x00007f9f830530a0@/Users/user/.rbenv/versions/2.6.1/lib/ruby/2.6.0/thwait.rb:91 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
```

Back