ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:68726] [CommonRuby - Feature #11026] [Open] How atomic should dynamic regexp with "once" flag be?
       [not found] <redmine.issue-11026.20150402220239@ruby-lang.org>
@ 2015-04-02 22:02 ` headius
  2015-04-02 22:09 ` [ruby-core:68727] [CommonRuby - Feature #11026] " headius
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: headius @ 2015-04-02 22:02 UTC (permalink / raw)
  To: ruby-core

Issue #11026 has been reported by Charles Nutter.

----------------------------------------
Feature #11026: How atomic should dynamic regexp with "once" flag be?
https://bugs.ruby-lang.org/issues/11026

* Author: Charles Nutter
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
The test_once_multithread test in ruby/test_regexp.rb tries to confirm that a dynamic "once" regexp is created atomically. Here's the test:

  def test_once_multithread
    m = Mutex.new
    pr3 = proc{|i|
      /#{m.unlock; sleep 0.5; i}/o
    }
    ary = []
    n = 0
    th1 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th2 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th1.join; th2.join
    assert_equal([/1/, /1/], ary)
  end

The logic here works as follows:

* Each thread locks the mutex, and then proceeds to execute the regexp with a different dynamic value
* Executing the regexp unlocks the mutex and applies the dynamic value

The test tries to guarantee that only the first thread to start processing the dynamic regexp will finally cache it, but I think this may be overreaching.

In order to make this test pass in a threaded implementation, the entire body of the regexp would need to be evaluated under synchronization, blocking other threads from doing the same. This would also require a synchronization lock to be acquired for every subsequent access of that regular expression, to ensure that multiple threads arriving at the code at the same time don't try to run the code at the same time or update the cached value twice. This could possibly be reduced with double-checked locking, but having this much synchronization overhead for a simple Ruby expression seems excessive.

Also, this synchronization would only protect threads from running the //o body twice; it does not guarantee ordering of those threads outside of the //o, so if any users depended on this "first thread wins" behavior, they'd still be surprised because they can't guarantee which thread hits the code first.

I believe this test should *only* confirm that all threads see the same regexp result, rather than trying to test that only one thread ever evaluates the regexp.

As far as specified behavior, I believe the only guarantee //o should make is that it will cache exactly one value and never execute again after that value has been cached, rather than making guarantees about the atomicity of dynamic operations within that regexp. In short, it should guarantee all threads see the same //o expression.

Thoughts?



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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:68727] [CommonRuby - Feature #11026] How atomic should dynamic regexp with "once" flag be?
       [not found] <redmine.issue-11026.20150402220239@ruby-lang.org>
  2015-04-02 22:02 ` [ruby-core:68726] [CommonRuby - Feature #11026] [Open] How atomic should dynamic regexp with "once" flag be? headius
@ 2015-04-02 22:09 ` headius
  2015-04-02 23:45 ` [ruby-core:68730] " nobu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: headius @ 2015-04-02 22:09 UTC (permalink / raw)
  To: ruby-core

Issue #11026 has been updated by Charles Nutter.


Filed https://github.com/jruby/jruby/issues/2798 to track this in JRuby.

----------------------------------------
Feature #11026: How atomic should dynamic regexp with "once" flag be?
https://bugs.ruby-lang.org/issues/11026#change-52011

* Author: Charles Nutter
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
The test_once_multithread test in ruby/test_regexp.rb tries to confirm that a dynamic "once" regexp is created atomically. Here's the test:

  def test_once_multithread
    m = Mutex.new
    pr3 = proc{|i|
      /#{m.unlock; sleep 0.5; i}/o
    }
    ary = []
    n = 0
    th1 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th2 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th1.join; th2.join
    assert_equal([/1/, /1/], ary)
  end

The logic here works as follows:

* Each thread locks the mutex, and then proceeds to execute the regexp with a different dynamic value
* Executing the regexp unlocks the mutex and applies the dynamic value

The test tries to guarantee that only the first thread to start processing the dynamic regexp will finally cache it, but I think this may be overreaching.

In order to make this test pass in a threaded implementation, the entire body of the regexp would need to be evaluated under synchronization, blocking other threads from doing the same. This would also require a synchronization lock to be acquired for every subsequent access of that regular expression, to ensure that multiple threads arriving at the code at the same time don't try to run the code at the same time or update the cached value twice. This could possibly be reduced with double-checked locking, but having this much synchronization overhead for a simple Ruby expression seems excessive.

Also, this synchronization would only protect threads from running the //o body twice; it does not guarantee ordering of those threads outside of the //o, so if any users depended on this "first thread wins" behavior, they'd still be surprised because they can't guarantee which thread hits the code first.

I believe this test should *only* confirm that all threads see the same regexp result, rather than trying to test that only one thread ever evaluates the regexp.

As far as specified behavior, I believe the only guarantee //o should make is that it will cache exactly one value and never execute again after that value has been cached, rather than making guarantees about the atomicity of dynamic operations within that regexp. In short, it should guarantee all threads see the same //o expression.

Thoughts?



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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:68730] [CommonRuby - Feature #11026] How atomic should dynamic regexp with "once" flag be?
       [not found] <redmine.issue-11026.20150402220239@ruby-lang.org>
  2015-04-02 22:02 ` [ruby-core:68726] [CommonRuby - Feature #11026] [Open] How atomic should dynamic regexp with "once" flag be? headius
  2015-04-02 22:09 ` [ruby-core:68727] [CommonRuby - Feature #11026] " headius
@ 2015-04-02 23:45 ` nobu
  2015-04-03  4:15 ` [ruby-core:68735] " headius
  2015-07-09  5:11 ` [ruby-core:69907] " 2851820660
  4 siblings, 0 replies; 5+ messages in thread
From: nobu @ 2015-04-02 23:45 UTC (permalink / raw)
  To: ruby-core

Issue #11026 has been updated by Nobuyoshi Nakada.

Description updated

You mean the last assertion should be that `ary` just has same regexps, not the exact values?

----------------------------------------
Feature #11026: How atomic should dynamic regexp with "once" flag be?
https://bugs.ruby-lang.org/issues/11026#change-52016

* Author: Charles Nutter
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
The `test_once_multithread` test in ruby/test_regexp.rb tries to confirm that a dynamic "once" regexp is created atomically. Here's the test:

~~~ruby
  def test_once_multithread
    m = Mutex.new
    pr3 = proc{|i|
      /#{m.unlock; sleep 0.5; i}/o
    }
    ary = []
    n = 0
    th1 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th2 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th1.join; th2.join
    assert_equal([/1/, /1/], ary)
  end
~~~

The logic here works as follows:

* Each thread locks the mutex, and then proceeds to execute the regexp with a different dynamic value
* Executing the regexp unlocks the mutex and applies the dynamic value

The test tries to guarantee that only the first thread to start processing the dynamic regexp will finally cache it, but I think this may be overreaching.

In order to make this test pass in a threaded implementation, the entire body of the regexp would need to be evaluated under synchronization, blocking other threads from doing the same. This would also require a synchronization lock to be acquired for every subsequent access of that regular expression, to ensure that multiple threads arriving at the code at the same time don't try to run the code at the same time or update the cached value twice. This could possibly be reduced with double-checked locking, but having this much synchronization overhead for a simple Ruby expression seems excessive.

Also, this synchronization would only protect threads from running the `//o` body twice; it does not guarantee ordering of those threads outside of the `//o`, so if any users depended on this "first thread wins" behavior, they'd still be surprised because they can't guarantee which thread hits the code first.

I believe this test should *only* confirm that all threads see the same regexp result, rather than trying to test that only one thread ever evaluates the regexp.

As far as specified behavior, I believe the only guarantee `//o` should make is that it will cache exactly one value and never execute again after that value has been cached, rather than making guarantees about the atomicity of dynamic operations within that regexp. In short, it should guarantee all threads see the same `//o` expression.

Thoughts?




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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:68735] [CommonRuby - Feature #11026] How atomic should dynamic regexp with "once" flag be?
       [not found] <redmine.issue-11026.20150402220239@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2015-04-02 23:45 ` [ruby-core:68730] " nobu
@ 2015-04-03  4:15 ` headius
  2015-07-09  5:11 ` [ruby-core:69907] " 2851820660
  4 siblings, 0 replies; 5+ messages in thread
From: headius @ 2015-04-03  4:15 UTC (permalink / raw)
  To: ruby-core

Issue #11026 has been updated by Charles Nutter.


Nobuyoshi Nakada wrote:
> You mean the last assertion should be that `ary` just has same regexps, not the exact values?

I would find that more acceptable than synchronizing around all the embedded code in a dynamic regexp.

#6701 is interesting. I would claim that both cases are abnormal exits from code and therefor the "once" regexp never completes processing, but I cannot read Japanese to understand the bug.

I guess my general proposal is that we can only really guarantee that one thread and only one thread will ever complete processing a "once" regexp, though multiple may start processing.

----------------------------------------
Feature #11026: How atomic should dynamic regexp with "once" flag be?
https://bugs.ruby-lang.org/issues/11026#change-52020

* Author: Charles Nutter
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
The `test_once_multithread` test in ruby/test_regexp.rb tries to confirm that a dynamic "once" regexp is created atomically. Here's the test:

~~~ruby
  def test_once_multithread
    m = Mutex.new
    pr3 = proc{|i|
      /#{m.unlock; sleep 0.5; i}/o
    }
    ary = []
    n = 0
    th1 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th2 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th1.join; th2.join
    assert_equal([/1/, /1/], ary)
  end
~~~

The logic here works as follows:

* Each thread locks the mutex, and then proceeds to execute the regexp with a different dynamic value
* Executing the regexp unlocks the mutex and applies the dynamic value

The test tries to guarantee that only the first thread to start processing the dynamic regexp will finally cache it, but I think this may be overreaching.

In order to make this test pass in a threaded implementation, the entire body of the regexp would need to be evaluated under synchronization, blocking other threads from doing the same. This would also require a synchronization lock to be acquired for every subsequent access of that regular expression, to ensure that multiple threads arriving at the code at the same time don't try to run the code at the same time or update the cached value twice. This could possibly be reduced with double-checked locking, but having this much synchronization overhead for a simple Ruby expression seems excessive.

Also, this synchronization would only protect threads from running the `//o` body twice; it does not guarantee ordering of those threads outside of the `//o`, so if any users depended on this "first thread wins" behavior, they'd still be surprised because they can't guarantee which thread hits the code first.

I believe this test should *only* confirm that all threads see the same regexp result, rather than trying to test that only one thread ever evaluates the regexp.

As far as specified behavior, I believe the only guarantee `//o` should make is that it will cache exactly one value and never execute again after that value has been cached, rather than making guarantees about the atomicity of dynamic operations within that regexp. In short, it should guarantee all threads see the same `//o` expression.

Thoughts?




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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:69907] [CommonRuby - Feature #11026] How atomic should dynamic regexp with "once" flag be?
       [not found] <redmine.issue-11026.20150402220239@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2015-04-03  4:15 ` [ruby-core:68735] " headius
@ 2015-07-09  5:11 ` 2851820660
  4 siblings, 0 replies; 5+ messages in thread
From: 2851820660 @ 2015-07-09  5:11 UTC (permalink / raw)
  To: ruby-core

Issue #11026 has been updated by 11 22.


http://www.software-rating.com/
http://www.smartlogi.com/  
http://www.shareorder.com/  
http://www.gzs168.com/  
http://www.aimooimage.com/    
http://www.chinatowngate.net/

http://www.inspiredhypnosis.co.uk/daocplat.html
http://the303plan.com/tibiagoldforsale.html

----------------------------------------
Feature #11026: How atomic should dynamic regexp with "once" flag be?
https://bugs.ruby-lang.org/issues/11026#change-53326

* Author: Charles Nutter
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
The `test_once_multithread` test in ruby/test_regexp.rb tries to confirm that a dynamic "once" regexp is created atomically. Here's the test:

~~~ruby
  def test_once_multithread
    m = Mutex.new
    pr3 = proc{|i|
      /#{m.unlock; sleep 0.5; i}/o
    }
    ary = []
    n = 0
    th1 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th2 = Thread.new{m.lock; ary << pr3.call(n+=1)}
    th1.join; th2.join
    assert_equal([/1/, /1/], ary)
  end
~~~

The logic here works as follows:

* Each thread locks the mutex, and then proceeds to execute the regexp with a different dynamic value
* Executing the regexp unlocks the mutex and applies the dynamic value

The test tries to guarantee that only the first thread to start processing the dynamic regexp will finally cache it, but I think this may be overreaching.

In order to make this test pass in a threaded implementation, the entire body of the regexp would need to be evaluated under synchronization, blocking other threads from doing the same. This would also require a synchronization lock to be acquired for every subsequent access of that regular expression, to ensure that multiple threads arriving at the code at the same time don't try to run the code at the same time or update the cached value twice. This could possibly be reduced with double-checked locking, but having this much synchronization overhead for a simple Ruby expression seems excessive.

Also, this synchronization would only protect threads from running the `//o` body twice; it does not guarantee ordering of those threads outside of the `//o`, so if any users depended on this "first thread wins" behavior, they'd still be surprised because they can't guarantee which thread hits the code first.

I believe this test should *only* confirm that all threads see the same regexp result, rather than trying to test that only one thread ever evaluates the regexp.

As far as specified behavior, I believe the only guarantee `//o` should make is that it will cache exactly one value and never execute again after that value has been cached, rather than making guarantees about the atomicity of dynamic operations within that regexp. In short, it should guarantee all threads see the same `//o` expression.

Thoughts?




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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-07-09  4:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-11026.20150402220239@ruby-lang.org>
2015-04-02 22:02 ` [ruby-core:68726] [CommonRuby - Feature #11026] [Open] How atomic should dynamic regexp with "once" flag be? headius
2015-04-02 22:09 ` [ruby-core:68727] [CommonRuby - Feature #11026] " headius
2015-04-02 23:45 ` [ruby-core:68730] " nobu
2015-04-03  4:15 ` [ruby-core:68735] " headius
2015-07-09  5:11 ` [ruby-core:69907] " 2851820660

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).