Project

General

Profile

Actions

Bug #20082

open

Killing fibers across threads: unexpected exception

Added by zverok (Victor Shepelev) 11 months ago. Updated 8 months ago.

Status:
Assigned
Target version:
-
[ruby-core:115881]

Description

For providing the example in a changelog, I tried to imitate killing fibers belonging to other threads.
Documentation claims

Raises FiberError if called on a fiber belonging to another thread.

So, I created this artificial example to check how it works:

fibers = []

Thread.new {
  f = Fiber.new { (1..).each { sleep(0.1) } }
  fibers << f
  f.resume
}
sleep(0.1) # to make sure the thread has started

fibers.last.kill

The example indeed fails with FiberError, but the error message is confusing:

in `kill': attempt to resume a resumed fiber (double resume) (FiberError)

Is this an expected message for such case? Or am I misunderstanding something?

Updated by zverok (Victor Shepelev) 11 months ago

UPD: OTOH, without resuming, the code doesn't see any problem at all (despite the claim about killing other thread's fibers):

fibers = []

Thread.new {
  f = Fiber.new { (1..).each { sleep(0.1) } }
  fibers << f
}
sleep(0.1) # to make sure the thread have started

p fibers.last.kill
#=> #<Fiber:0x00007f73f682c078 examples/fiber_kill.rb:7 (terminated)>

Updated by rubyFeedback (robert heiler) 11 months ago

The error message is indeed somewhat peculiar:

"attempt to resume a resumed fiber ( double resume )"

I am not sure what "double resume" means here. But, even aside
from this, I could not even try to want to explain what "to
resume a resumed fiber" really means. Perhaps something else
was meant here? Or it was meant to convey that the code tried
to resume an already-resumed fiber. Either way it is indeed
peculiar.

I'd even be radical and suggest to get rid of fibers and instead
put everything under Thread, but I guess that is not possible
for various reasons. To me Threads seem easier to understand
than Fibers though.

Updated by ioquatix (Samuel Williams) 11 months ago

Raises FiberError if called on a fiber belonging to another thread.

I agree the error is a little confusing, but the reality is it's probably okay.

"in `kill': attempt to resume a resumed fiber (double resume) (FiberError)"

You are literally reaching across into a fiber which is currently resumed and executing sleep. This is a text book definition of a double resume.

To get the error message I imagine you are after:

fibers = []

Thread.new {
  f = Fiber.new { Fiber.yield }
  f.resume
  fibers << f
}.join

fibers.last.kill

without resuming, the code doesn't see any problem at all (despite the claim about killing other thread's fibers):

A fiber is lazily constructed according to the first thread it is resumed on. So, this behaviour looks okay to me.

Actions #4

Updated by hsbt (Hiroshi SHIBATA) 8 months ago

  • Status changed from Open to Assigned
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0