Actions
Bug #18904
closedMutex and Fiber: No live threads left. Deadlock? (fatal)
    Bug #18904:
    Mutex and Fiber: No live threads left. Deadlock? (fatal)
  
Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21]
Description
Hi,
I was investigating an issue with the climate_control gem and minitest-around and it seems like the bug is coming from Ruby:
def around(&block)
  Fiber.new do |context, resume|
    context.instance_exec(resume, &block)
  end.resume
end
MUTEX = Mutex.new
around do
  MUTEX.synchronize do
    around do
      MUTEX.synchronize do
      end
    end
  end
end
test.rb:12:in `synchronize': No live threads left. Deadlock? (fatal)
1 threads, 1 sleeps current:0x0000000126804080 main thread:0x0000000126804080
* #<Thread:0x00000001043b8d50 sleep_forever>
   rb_thread_t:0x0000000126804080 native:0x0000000104330580 int:0
   
	from test.rb:12:in `block (3 levels) in <main>'
	from test.rb:3:in `instance_exec'
	from test.rb:3:in `block in around'
        
           Updated by dorianmariefr (Dorian Marié) over 3 years ago
          Updated by dorianmariefr (Dorian Marié) over 3 years ago
          
          
        
        
      
      Same error happens with Monitor
        
           Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
          Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
          
          
        
        
      
      - Status changed from Open to Rejected
This isn't a bug.  Mutex is not designed to be reentrant, so that will always fail in recursive use. Monitor is only reentrant in the same fiber, and you are using a separate fiber, so that should fail as well in this case.  The Monitor case works in Ruby <3.0, before Mutex/Monitor were made fiber aware.  However, this behavior change is not a regression, it was explicitly designed this way.
        
           Updated by dorianmariefr (Dorian Marié) over 3 years ago
          Updated by dorianmariefr (Dorian Marié) over 3 years ago
          
          
        
        
      
      What would you suggest using instead?
        
           Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
          Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
          
          
        
        
      
      dorianmariefr (Dorian Marié) wrote in #note-3:
What would you suggest using instead?
Stop nesting the calls?:
around do                                                                                                                                                                                                                               
  MUTEX.synchronize do                                                                                                                                                                                                                  
    # don't call around here                                                                                                                                                                                                                               
  end                                                                                                                                                                                                                                   
end  
Actions