Bug #10540
closedYielded fibers do not execute ensure blocks
Description
When a thread has paused fibers, if an exception occurs anywhere in the thread, ensure blocks in the paused fibers do not execute.
The effect of this is that block-scoped resources (like File.open, Mutex#synchronize, ActiveRecord transactions) can easily leak due to non-local effects. This may result in strange effects, like checking connections back into a connection pool that are in the wrong state, where the correct state was guarded with an ensure block.
Here is a very simple repro of this situation:
Thread.new {
  Fiber.new {
    begin
      puts "YIELD"
      Fiber.yield
    ensure
      puts "UNWIND"
    end
  }.resume
  raise
}
Expected result: YIELD is printed, followed by UNWIND
Actual result: YIELD is printed, but UNWIND is never printed
        
          
          Updated by normalperson (Eric Wong) almost 11 years ago
          
          
        
        
      
      This seems unfortunate.  I'm not sure if there's a good way to do
this automatically with current APIs because Fibers require
explicit scheduling.
Perhaps storing Fibers in Thread.current and having a
terminate_all_fibers method can be helpful:
Thread.new do
  begin
    do_something_which_creates_fibers
  ensure
    # all thread-local fibers are resumed until they're dead
    terminate_all_fibers
  end
end
        
          
          Updated by ko1 (Koichi Sasada) almost 11 years ago
          
          
        
        
      
      - Assignee set to ko1 (Koichi Sasada)
 - Target version set to 2.6
 
This issue is a known bug.
[Bug #595]: Fiber ignores ensure clause
(3 digits!)
Rubinius supports it.
This feature is not impossible, but a bit difficult because there are two ENSURE points.
- Owner thread is terminated.
 - 
Fiberobject is collected. 
In this issue, (1) is pointed out. It is easy to implement by sending EXIT exception for owned fibers.
However, (2) is a problem. We can not use finalizers for each fibers because it is too late (in finalizer, Fiber object should be already terminated). To solve this issue, we need to separate fiber handler and fiber cotext itself. In other words, it is possible, but tough hack.
And another issue is compatibility. It is too late to fix this issue for 2.2.
I try to implement this fix and apply in early 2015.
        
          
          Updated by ko1 (Koichi Sasada) almost 9 years ago
          
          
        
        
      
      - Related to Bug #595: Fiber ignores ensure clause added
 
        
          
          Updated by ko1 (Koichi Sasada) almost 9 years ago
          
          
        
        
      
      - Status changed from Open to Closed
 
See #595