Issue #15000 has been updated by shugo (Shugo Maeda).

Status changed from Closed to Assigned
Assignee changed from shugo (Shugo Maeda) to Eregon (Benoit Daloze)

Reverted r65822 because mon_initialize_spec.rb fails:

```
    1)
    MonitorMixin#mon_initialize can be called in initialize_copy to get a new M
utex and used with synchronize ERROR
    ThreadError: already initialized
    /home/shugo/src/ruby/lib/monitor.rb:255:in `mon_initialize'
    /home/shugo/src/ruby/spec/ruby/library/monitor/mon_initialize_spec.rb:19:in
 `initialize_copy'
    /home/shugo/src/ruby/spec/ruby/library/monitor/mon_initialize_spec.rb:28:in
 `initialize_dup'
    /home/shugo/src/ruby/spec/ruby/library/monitor/mon_initialize_spec.rb:28:in
 `dup'
    /home/shugo/src/ruby/spec/ruby/library/monitor/mon_initialize_spec.rb:28:in
 `block (2 levels) in <top (required)>'
    /home/shugo/src/ruby/spec/ruby/library/monitor/mon_initialize_spec.rb:4:in
`<top (required)>'
```

mon_initialized may be used to re-initialize copied objects intentionally.

It's possible to add a new option such as `force:` to mon_initialize, but
the default value should be `true` for backward compatibility, and it's
not helpful to avoid unintentional re-initialization.

What do you think, Eregon?



----------------------------------------
Feature #15000: Prevent to initialize MonitorMixin twice
https://bugs.ruby-lang.org/issues/15000#change-74971

* Author: Eregon (Benoit Daloze)
* Status: Assigned
* Priority: Normal
* Assignee: Eregon (Benoit Daloze)
* Target version: 
----------------------------------------
Some libraries or tests unfortunately do something like:

~~~ ruby
require 'monitor'
class Foo
  include MonitorMixin
  def initialize(*args)
    super()
    mon_initialize
  end
end
~~~

This unfortunately ends up initializing the monitor twice.
If the two monitor initializations are done concurrently,
we can end up with two threads entering the same Monitor concurrently,
as they can acquire two different Mutex instances.

I'd proposed to raise an exception if `@mon_mutex` is already set, like `raise "already initialized" if @mon_mutex`.
This doesn't fully solve the problem if allocate is used and #initialize is called concurrently, but then I think it's the user's fault.

I originally found this problem while running Rails tests, but I can't find the exact source file anymore causing this.
Still, I think it's better to check here.



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