rubinius/rubinius — Issue #1480: Thread-local variable bug when using Fibers
Author: tarcieri
Created: 2012-01-02 05:54:12+00:00
State: open

First let me make sure my understanding of the relationship between thread local variables and fibers is correct:

Fibers have their own set of thread-local variables that are set whenever a fiber is resumed. These are not shared with the root fiber of the parent thread.

If that's the case, I'm seeing a bug in thread-local variables that's reproducible 100% of the time:

* clone tarcieri/celluloid
* checkout commit a6abb841c362bc04ac0b740690aaa1a1194a9216
* run the specs

The problem manifests as:

E, [2012-01-01T21:46:58.235892 #12175] ERROR -- : signaling error
Celluloid::DeadTaskError: cannot resume a dead task

Adding a bit of debugging instrumentation around Fiber.yield here will reveal the problem:

https://github.com/tarcieri/celluloid/blob/a6abb841c362bc04ac0b740690aaa1a1194a9216/lib/celluloid/task.rb#L20

Celluloid was storing the current task object (a wrapper around a fiber) in Thread.current[:task]. Before Fiber.yield here the value is correct. However, upon resuming the Fiber the value of Thread.current[:task] has changed and appears to reference a previous value from a different fiber.

I ended up reimplementing this little bit to store the current task in Fiber.current and that version does not experience this problem. I also did not see it on 1.9.3 and JRuby.