Project

General

Profile

Bug #14998

Race conditions in MonitorMixin when interrupted

Added by Eregon (Benoit Daloze) about 1 year ago. Updated 12 months ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.6.0dev (2018-08-16 trunk 64394) [x86_64-linux]
[ruby-core:88502]

Description

From https://bugs.ruby-lang.org/issues/14859#note-9

The code of MonitorMixin#wait is:

    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.

Associated revisions

Revision 6ec1720a
Added by shugo (Shugo Maeda) 12 months ago

lib/monitor.rb: avoid race conditions by Thread.handle_interrupt

Suggested by Benoit Daloze. [ruby-core:88502] [Bug #14998]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66061 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 66061
Added by shugo (Shugo Maeda) 12 months ago

lib/monitor.rb: avoid race conditions by Thread.handle_interrupt

Suggested by Benoit Daloze. [ruby-core:88502] [Bug #14998]

Revision 66061
Added by shugo (Shugo Maeda) 12 months ago

lib/monitor.rb: avoid race conditions by Thread.handle_interrupt

Suggested by Benoit Daloze. [ruby-core:88502] [Bug #14998]

History

Updated by shugo (Shugo Maeda) 12 months ago

Eregon (Benoit Daloze) wrote:

From https://bugs.ruby-lang.org/issues/14859#note-9

The code of MonitorMixin#wait is:

    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?

    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
#2

Updated by shugo (Shugo Maeda) 12 months ago

  • Status changed from Open to Closed

Applied in changeset trunk|r66061.


lib/monitor.rb: avoid race conditions by Thread.handle_interrupt

Suggested by Benoit Daloze. [ruby-core:88502] [Bug #14998]

Also available in: Atom PDF