-
Notifications
You must be signed in to change notification settings - Fork 605
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3674 from rubinius/fibers
WIP Rewrite Fibers to use pthreads
- v5.0
- v4.20
- v4.19
- v4.18
- v4.17
- v4.16
- v4.15
- v4.14
- v4.13
- v4.12
- v4.11
- v4.10
- v4.9
- v4.8
- v4.7
- v4.6
- v4.5
- v4.4
- v4.3
- v4.2
- v4.1
- v4.0
- v3.107
- v3.106
- v3.105
- v3.104
- v3.103
- v3.102
- v3.101
- v3.100
- v3.99
- v3.98
- v3.97
- v3.96
- v3.95
- v3.94
- v3.93
- v3.92
- v3.91
- v3.90
- v3.89
- v3.88
- v3.87
- v3.86
- v3.85
- v3.84
- v3.83
- v3.82
- v3.81
- v3.80
- v3.79
- v3.78
- v3.77
- v3.76
- v3.75
- v3.74
- v3.73
- v3.72
- v3.71
- v3.70
- v3.69
- v3.68
- v3.67
- v3.66
- v3.65
- v3.64
- v3.63
- v3.62
- v3.61
- v3.60
- v3.59
- v3.58
- v3.57
- v3.56
- v3.55
- v3.54
- v3.53
- v3.52
- v3.51
- v3.50
- v3.49
- v3.48
- v3.47
- v3.46
- v3.45
- v3.44
- v3.43
- v3.42
- v3.41
Showing
63 changed files
with
1,169 additions
and
1,777 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,63 @@ | ||
module Rubinius | ||
class Fiber | ||
attr_reader :stack_size | ||
attr_reader :thread_name | ||
attr_reader :fiber_id | ||
attr_reader :source | ||
class Fiber | ||
attr_reader :stack_size | ||
attr_reader :thread_name | ||
attr_reader :fiber_id | ||
attr_reader :source | ||
|
||
def self.new(**kw, &block) | ||
if block.nil? | ||
raise ArgumentError, "Fiber.new requires a block" | ||
end | ||
|
||
def self.new(**kw, &block) | ||
if block.nil? | ||
raise ArgumentError, "Fiber.new requires a block" | ||
end | ||
stack_size = Rubinius::Type.try_convert kw[:stack_size], Fixnum, :to_int | ||
|
||
stack_size = Rubinius::Type.try_convert kw[:stack_size], Fixnum, :to_int | ||
Rubinius.invoke_primitive :fiber_new, stack_size, block, self | ||
end | ||
|
||
Rubinius.invoke_primitive :fiber_new, stack_size, block, self | ||
end | ||
def self.current | ||
Rubinius.primitive :fiber_s_current | ||
raise PrimitiveFailure, "Fiber.current primitive failed" | ||
end | ||
|
||
def self.current | ||
Rubinius.primitive :fiber_s_current | ||
raise PrimitiveFailure, "Rubinius::Fiber.current failed" | ||
end | ||
def self.yield(*args) | ||
Rubinius.primitive :fiber_s_yield | ||
raise PrimitiveFailure, "Fiber.yield primitive failed" | ||
end | ||
|
||
def self.yield(*args) | ||
Rubinius.primitive :fiber_s_yield | ||
raise PrimitiveFailure, "Rubinius::Fiber.yield failed" | ||
end | ||
def self.list | ||
Rubinius.primitive :fiber_s_list | ||
raise PrimitiveFailure, "Fiber.list primitive failed" | ||
end | ||
|
||
def resume(*args) | ||
Rubinius.primitive :fiber_resume | ||
raise PrimitiveFailure, "Rubinius::Fiber#resume failed" | ||
end | ||
def self.main | ||
Rubinius.primitive :fiber_s_main | ||
raise PrimitiveFailure, "Fiber.main primitive failed" | ||
end | ||
|
||
def transfer(*args) | ||
Rubinius.primitive :fiber_transfer | ||
raise PrimitiveFailure, "Rubinius::Fiber#transfer failed" | ||
end | ||
def status | ||
Rubinius.primitive :fiber_status | ||
raise PrimitiveFailure, "Fiber#status primitive failed" | ||
end | ||
|
||
def alive? | ||
!@dead | ||
end | ||
def resume(*args) | ||
Rubinius.primitive :fiber_resume | ||
raise PrimitiveFailure, "Fiber#resume primitive failed" | ||
end | ||
|
||
def inspect | ||
str = "#<#{self.class}:0x#{object_id.to_s(16)} thread_name=#{@thread_name} fiber_id=#{@fiber_id} status=#{alive? ? "alive" : "dead"}" | ||
str << " source=#{@source}" if @source | ||
str << ">" | ||
end | ||
def transfer(*args) | ||
Rubinius.primitive :fiber_transfer | ||
raise PrimitiveFailure, "Fiber#transfer primitive failed" | ||
end | ||
|
||
def alive? | ||
status != "dead" | ||
end | ||
|
||
def inspect | ||
str = "#<#{self.class}:0x#{object_id.to_s(16)} thread_name=#{@thread_name} fiber_id=#{@fiber_id} status=#{status}" | ||
str << " source=#{@source}" if @source | ||
str << ">" | ||
end | ||
|
||
alias_method :to_s, :inspect | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
require File.expand_path('../../../spec_helper', __FILE__) | ||
|
||
describe "Fiber.list" do | ||
it "returns an Array" do | ||
Fiber.list.should be_an_instance_of(Array) | ||
end | ||
|
||
it "returns non-dead Fibers" do | ||
f1 = Fiber.new { } | ||
f2 = Fiber.new { } | ||
|
||
f2.resume | ||
|
||
Fiber.list.should include(f1) | ||
Fiber.list.should_not include(f2) | ||
|
||
f1.resume | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require File.expand_path('../../../spec_helper', __FILE__) | ||
|
||
describe "Fiber.list" do | ||
it "returns the root Fiber for the thread" do | ||
Fiber.main.should be_an_instance_of(Fiber) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,123 @@ | ||
require File.expand_path('../../../spec_helper', __FILE__) | ||
require File.expand_path('../../../shared/fiber/resume', __FILE__) | ||
|
||
with_feature :fiber do | ||
describe "Fiber#resume" do | ||
it_behaves_like :fiber_resume, :resume | ||
end | ||
it "can be invoked from the root Fiber" do | ||
fiber = Fiber.new { :fiber } | ||
fiber.resume.should == :fiber | ||
end | ||
|
||
it "raises a FiberError if invoked from a different Thread" do | ||
fiber = Fiber.new { } | ||
lambda do | ||
Thread.new do | ||
fiber.resume | ||
end.join | ||
end.should raise_error(FiberError) | ||
fiber.resume | ||
end | ||
|
||
describe "Fiber#resume" do | ||
it "returns control to the calling Fiber if called from one" do | ||
fiber1 = Fiber.new { :fiber1 } | ||
fiber2 = Fiber.new { fiber1.resume; :fiber2 } | ||
fiber2.resume.should == :fiber2 | ||
end | ||
|
||
with_feature :fork do | ||
ruby_bug "redmine #595", "2.1.0" do | ||
it "executes the ensure clause" do | ||
rd, wr = IO.pipe | ||
if Kernel::fork then | ||
wr.close | ||
rd.read.should == "executed" | ||
rd.close | ||
else | ||
rd.close | ||
Fiber.new { | ||
begin | ||
Fiber.yield | ||
ensure | ||
wr.write "executed" | ||
end | ||
}.resume | ||
exit 0 | ||
it "passes control to the beginning of the block on first invocation" do | ||
invoked = false | ||
fiber = Fiber.new { invoked = true } | ||
fiber.resume | ||
invoked.should be_true | ||
end | ||
|
||
it "returns the last value encountered on first invocation" do | ||
fiber = Fiber.new { false; true } | ||
fiber.resume.should be_true | ||
end | ||
|
||
it "runs until the end of the block" do | ||
obj = mock('obj') | ||
obj.should_receive(:do).once | ||
fiber = Fiber.new { 1 + 2; a = "glark"; obj.do } | ||
fiber.resume | ||
end | ||
|
||
it "runs until Fiber.yield" do | ||
obj = mock('obj') | ||
obj.should_not_receive(:do) | ||
fiber = Fiber.new { 1 + 2; Fiber.yield; obj.do } | ||
fiber.resume | ||
end | ||
|
||
it "resumes from the last call to Fiber.yield on subsequent invocations" do | ||
fiber = Fiber.new { Fiber.yield :first; :second } | ||
fiber.resume.should == :first | ||
fiber.resume.should == :second | ||
end | ||
|
||
it "accepts any number of arguments" do | ||
fiber = Fiber.new { |a| } | ||
lambda { fiber.resume(*(1..10).to_a) }.should_not raise_error | ||
end | ||
|
||
it "sets the block parameters to its arguments on the first invocation" do | ||
first = mock('first') | ||
first.should_receive(:arg).with(:first).twice | ||
fiber = Fiber.new { |arg| first.arg arg; Fiber.yield; first.arg arg; } | ||
fiber.resume(:first) | ||
fiber.resume(:second) | ||
end | ||
|
||
it "raises a FiberError if the Fiber is dead" do | ||
fiber = Fiber.new { true } | ||
fiber.resume | ||
lambda { fiber.resume }.should raise_error(FiberError) | ||
end | ||
|
||
it "raises a LocalJumpError if the block includes a return statement" do | ||
fiber = Fiber.new { return; } | ||
lambda { fiber.resume }.should raise_error(LocalJumpError) | ||
end | ||
|
||
it "raises a LocalJumpError if the block includes a break statement" do | ||
fiber = Fiber.new { break; } | ||
lambda { fiber.resume }.should raise_error(LocalJumpError) | ||
end | ||
|
||
# ruby_bug "redmine #595", "2.1.0" | ||
it "executes the ensure clause" do | ||
rd, wr = IO.pipe | ||
|
||
pid = Kernel::fork do | ||
rd.close | ||
f = Fiber.new do | ||
begin | ||
Fiber.yield | ||
ensure | ||
wr.write "executed" | ||
end | ||
end | ||
|
||
# The apparent issue is that when Fiber.yield executes, control | ||
# "leaves" the "ensure block" and so the ensure clause should run. But | ||
# control really does NOT leave the ensure block when Fiber.yield | ||
# executes. It merely pauses there. To require ensure to run when a | ||
# Fiber is suspended then makes ensure-in-a-Fiber-context different | ||
# than ensure-in-a-Thread-context and this would be very confusing. | ||
f.resume | ||
|
||
# When we execute the second #resume call, the ensure block DOES exit, | ||
# the ensure clause runs. This is Ruby behavior as of 2.3.1. | ||
f.resume | ||
|
||
exit 0 | ||
end | ||
|
||
wr.close | ||
Process.waitpid pid | ||
|
||
rd.read.should == "executed" | ||
rd.close | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
require File.expand_path('../../../spec_helper', __FILE__) | ||
|
||
with_feature :fiber do | ||
describe "Fiber#transfer" do | ||
it "can be invoked from the root Fiber" do | ||
fiber = Fiber.new { :fiber } | ||
fiber.transfer.should == :fiber | ||
end | ||
|
||
it "returns to the root Fiber when finished" do | ||
f1 = Fiber.new { :fiber_1 } | ||
f2 = Fiber.new { f1.transfer; :fiber_2 } | ||
|
||
f2.transfer.should == :fiber_1 | ||
f2.transfer.should == :fiber_2 | ||
end | ||
|
||
it "raises a FiberError if invoked from a different Thread" do | ||
fiber = Fiber.new { } | ||
lambda do | ||
Thread.new do | ||
fiber.transfer | ||
end.join | ||
end.should raise_error(FiberError) | ||
fiber.resume | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.