Bug #9432
closedThreadError [ Attempt to unlock a mutex which is locked by another thread ]
Description
I use ruby-2.0.0-p247. I seem to get this issue frequently in threaded environment. (Sidekiq)
I am not very sure if it a ruby thread issue as such or something I am doing wrong. If there is any more details you need I would be happy to provide you.
Operating system: Ubuntu
Trace
/home/ubuntu/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/thread.rb:188:in `synchronize'
/home/ubuntu/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/thread.rb:188:in `block in pop'
/home/ubuntu/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/thread.rb:187:in `handle_interrupt'
/home/ubuntu/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/thread.rb:187:in `pop'
Regards
Rajesh
Updated by normalperson (Eric Wong) almost 11 years ago
I use ruby-2.0.0-p247. I seem to get this issue frequently in threaded
environment. (Sidekiq)I am not very sure if it a ruby thread issue as such or something I am
doing wrong. If there is any more details you need I would be happy to
provide you.
Have you contacted the sidekiq author about this?
Updated by nagachika (Tomoyuki Chikanaga) almost 11 years ago
Hello, rajesh.
Thank you for your report.
Could you try to reproduce it with 2.1 and/or trunk?
Updated by aaron@serendipity.cx (Aaron Stone) almost 10 years ago
Note: Sidekiq does not appear to be using eventmachine, which has a similar bug at #9132. Any ideas on what is going on here? I can reproduce the bug from all releases of Ruby 2.0.0pxxx including 2.0.0p598.
Updated by normalperson (Eric Wong) almost 10 years ago
Can you show us a small test case? Which version of Sidekiq?
Note: this issue seems to not affect Ruby 2.1+ because thread.rb was
rewritten in C. I looked briefly and #9132 but I'd rather deal
with issues in pure Ruby or C, not C++.
Updated by hsbt (Hiroshi SHIBATA) almost 10 years ago
- Tracker changed from Backport to Bug
- Project changed from Backport200 to Ruby master
- ruby -v set to 2.0.0
Updated by aaron@serendipity.cx (Aaron Stone) almost 10 years ago
The error also shows up here: https://github.com/iconara/cql-rb/issues/68
This is not an issue with the applications or the gems, or that eventmachine is written in C++. It's an MRI Ruby problem in the 2.0 implementation of Queue.pop, which is different than the 1.9.3 implementation that does not have this problem.
Ruby 2.0 is a widely deployed and supported version.
I'd really appreciate if someone upstream would take this bug report seriously.
Updated by aaron@serendipity.cx (Aaron Stone) almost 10 years ago
In Ruby 1.9.3, thread.rb has Queue.pop defined as:
183 def pop(non_block=false)
184 @mutex.synchronize{
185 while true
186 if @que.empty?
187 raise ThreadError, "queue empty" if non_block
188 @waiting.push Thread.current
189 @mutex.sleep
190 else
191 return @que.shift
192 end
193 end
194 }
195 end
In Ruby 2.0, thread.rb has Queue.pop defined as:
186 def pop(non_block=false)
187 Thread.handle_interrupt(StandardError => :on_blocking) do
188 @mutex.synchronize do
189 while true
190 if @que.empty?
191 if non_block
192 raise ThreadError, "queue empty"
193 else
194 begin
195 @num_waiting += 1
196 @cond.wait @mutex
197 ensure
198 @num_waiting -= 1
199 end
200 end
201 else
202 return @que.shift
203 end
204 end
205 end
206 end
207 end
The use of ConditionVariable is new in 2.0 vs. 1.9.3, and I think it is causing the problem. In 1.9.3, Queue.push itself walks its @waiting array to find and wake up a thread that will consume the just-pushed element. In 2.0, Queue.push calls @cond.signal which then goes and looks for a thread to wake up.
Ok, here's the most salient difference:
In 1.9.3, Queue.push calls thread.wakeup on a consuming thread.
In 2.0, Queue.push calls ConditionVariable.signal calls thread.run on a consuming thread.
The difference is that thread.run also executes the scheduler immediately.
In Ruby 2.1 and up, thread.rb does not exist - it appears to be rewritten in C.
Updated by aaron@serendipity.cx (Aaron Stone) almost 10 years ago
Dear Ruby maintainers: this is still a problem. Please, help out here.
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- Status changed from Open to Closed