[ruby-core:89871] [Ruby trunk Bug#14998] Race conditions in MonitorMixin when interrupted

From: shugo@...
Date: 2018-11-19 08:57:15 UTC
List: ruby-core #89871
Issue #14998 has been updated by shugo (Shugo Maeda).


Eregon (Benoit Daloze) wrote:
> From https://bugs.ruby-lang.org/issues/14859#note-9
> 
> The code of MonitorMixin#wait is:
> 
> ~~~ ruby
>     def wait(timeout = nil)
>       @monitor.__send__(:mon_check_owner)
>       count = @monitor.__send__(:mon_exit_for_cond)
>       begin
>         @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
>         return true
>       ensure
>         # What if Thread#raise happens here?
>         @monitor.__send__(:mon_enter_for_cond, count)
>       end
>     end
> ~~~
> 
> Probably this code needs to carefully use Thread.handle_interrupt.

How about the following code?

```ruby
    def wait(timeout = nil)
      Thread.handle_interrupt(Exception => :never) do
        @monitor.__send__(:mon_check_owner)
        count = @monitor.__send__(:mon_exit_for_cond)
        begin
          Thread.handle_interrupt(Exception => :immediate) do
            @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
          end
          return true
        ensure
          @monitor.__send__(:mon_enter_for_cond, count)
        end
      end
    end
```


----------------------------------------
Bug #14998: Race conditions in MonitorMixin when interrupted
https://bugs.ruby-lang.org/issues/14998#change-74933

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Assignee: shugo (Shugo Maeda)
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-08-16 trunk 64394) [x86_64-linux]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
From https://bugs.ruby-lang.org/issues/14859#note-9

The code of MonitorMixin#wait is:

~~~ ruby
    def wait(timeout = nil)
      @monitor.__send__(:mon_check_owner)
      count = @monitor.__send__(:mon_exit_for_cond)
      begin
        @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
        return true
      ensure
        # What if Thread#raise happens here?
        @monitor.__send__(:mon_enter_for_cond, count)
      end
    end
~~~

Probably this code needs to carefully use Thread.handle_interrupt.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next