Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions core/fiber/current_scheduler_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require_relative '../../spec_helper'
require_relative 'fixtures/scheduler'

describe "Fiber.current_scheduler" do
it "returns nil when no scheduler is set" do
Fiber.scheduler.should == nil
Fiber.current_scheduler.should == nil
end

describe "when a scheduler is set" do
before :each do
@scheduler = FiberSpecs::LoggingScheduler.new
Fiber.set_scheduler(@scheduler)
end

after :each do
Fiber.set_scheduler(nil)
end

it "returns nil on the root Fiber, which is blocking" do
Fiber.current_scheduler.should == nil
end

it "returns the scheduler inside a non-blocking Fiber" do
seen = nil
Fiber.new(blocking: false) { seen = Fiber.current_scheduler }.resume
seen.should.equal?(@scheduler)
end

it "returns nil inside a blocking Fiber, where Fiber.scheduler still returns the scheduler" do
seen = nil
Fiber.new(blocking: true) { seen = [Fiber.scheduler, Fiber.current_scheduler] }.resume
seen.should == [@scheduler, nil]
end

it "returns nil inside a blocking Fiber nested in a non-blocking Fiber" do
seen = nil
Fiber.new(blocking: false) do
Fiber.new(blocking: true) { seen = Fiber.current_scheduler }.resume
end.resume
seen.should == nil
end

it "returns the scheduler inside a non-blocking Fiber nested in a blocking Fiber" do
seen = nil
Fiber.new(blocking: true) do
Fiber.new(blocking: false) { seen = Fiber.current_scheduler }.resume
end.resume
seen.should.equal?(@scheduler)
end

it "returns nil inside Fiber.blocking in a non-blocking Fiber" do
seen = nil
Fiber.new(blocking: false) { Fiber.blocking { seen = Fiber.current_scheduler } }.resume
seen.should == nil
end

it "returns the scheduler again after Fiber.blocking returns" do
seen = nil
Fiber.new(blocking: false) do
Fiber.blocking { }
seen = Fiber.current_scheduler
end.resume
seen.should.equal?(@scheduler)
end
end
end
5 changes: 5 additions & 0 deletions core/fiber/fixtures/scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ def block(*args)
Fiber.yield
end

def fiber(*args, &block)
@events << { event: :fiber, fiber: Fiber.current, args: args }
Fiber.new(blocking: false, &block).tap(&:resume)
end

def io_wait(*args)
@events << { event: :io_wait, fiber: Fiber.current, args: args }
Fiber.yield
Expand Down
69 changes: 69 additions & 0 deletions core/fiber/schedule_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require_relative '../../spec_helper'
require_relative 'fixtures/scheduler'

describe "Fiber.schedule" do
describe "when no scheduler is set" do
it "raises a RuntimeError" do
Fiber.scheduler.should == nil

-> {
Fiber.schedule { }
}.should.raise(RuntimeError)
end
end

describe "when a scheduler is set" do
before :each do
@scheduler = FiberSpecs::LoggingScheduler.new
Fiber.set_scheduler(@scheduler)
end

after :each do
Fiber.set_scheduler(nil)
end

it "calls the scheduler's #fiber hook" do
Fiber.schedule { }
@scheduler.events.map { |event| event[:event] }.should == [:fiber]
end

it "returns the Fiber which runs the block" do
scheduled = nil
fiber = Fiber.schedule { scheduled = Fiber.current }
fiber.should.equal?(scheduled)
end

it "can be called from inside a non-blocking Fiber" do
inner = nil

outer = Fiber.new(blocking: false) do
inner = Fiber.schedule { }
end
outer.resume

inner.should.is_a?(Fiber)
end

it "uses the scheduler of the Thread owning the Fiber it is called from" do
seen = nil

outer = Fiber.new(blocking: false) do
Fiber.schedule { seen = Fiber.scheduler }
end
outer.resume

seen.should.equal?(@scheduler)
end

it "runs the block in a Fiber which sees the scheduler as its current scheduler" do
seen = nil

outer = Fiber.new(blocking: false) do
Fiber.schedule { seen = Fiber.current_scheduler }
end
outer.resume

seen.should.equal?(@scheduler)
end
end
end