Skip to content

Commit

Permalink
The arguments of Thread.new need to be marked as shared between multi…
Browse files Browse the repository at this point in the history
…ple threads

* See #3179 (comment)
  • Loading branch information
eregon committed Jan 9, 2024
1 parent 8b4a7b3 commit 9f026cb
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Bug fixes:
* Fix some C API functions which were failing when called with Ruby values represented as Java primitives (#3352, @eregon).
* Fix `IO.select([io], nil, [io])` on macOS, it was hanging due to a bug in macOS `poll(2)` (#3346, @eregon, @andrykonchin).
* Run context cleanup such as showing the output of tools when `SignalException` and `Interrupt` escape (@eregon).
* The arguments of `Thread.new(*args, &block)` need to be marked as shared between multiple threads (#3179, @eregon).

Compatibility:

Expand Down
29 changes: 29 additions & 0 deletions spec/truffle/thread_safe_objects_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,35 @@ def wb; @wb; end
shared?(new_hash).should == true
end

describe "Thread.new's" do
it "block" do
obj = Object.new
t = Thread.new { sleep }
begin
shared?(obj).should == true
ensure
t.kill
t.join
end
end

# avoid capturing local variables in the spec example below
thread_body = proc { sleep }

it "arguments" do
obj1 = Object.new
obj2 = Object.new
t = Thread.new(obj1, obj2, &thread_body)
begin
shared?(obj1).should == true
shared?(obj2).should == true
ensure
t.kill
t.join
end
end
end

it "Fiber local variables which share the value (since they can be accessed from other threads)" do
require 'fiber'
# Create a new Thread to make sure the root Fiber is shared as expected
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/truffleruby/core/thread/ThreadNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ private Object init(RubyThread thread, RubyProc block, ArgumentsDescriptor descr

if (getLanguage().options.SHARED_OBJECTS_ENABLED) {
getContext().getThreadManager().startSharing(thread, sharingReason);
SharedObjects.shareDeclarationFrame(getLanguage(), block, info);
SharedObjects.shareBlockAndArguments(getLanguage(), block, args, info);
}

getContext().getThreadManager().initialize(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,14 @@ private static void shareContextRoots(RubyLanguage language, RubyContext context
}
}

public static void shareDeclarationFrame(RubyLanguage language, RubyProc block, String info) {
public static void shareBlockAndArguments(RubyLanguage language, RubyProc block, Object[] args, String info) {
if (language.options.SHARED_OBJECTS_DEBUG) {
RubyLanguage.LOGGER.info("sharing decl frame of " + info);
RubyLanguage.LOGGER.info("sharing block and arguments of " + info);
}

final Set<Object> objects = ObjectGraph.newObjectSet();
ObjectGraph.getObjectsInFrame(block.declarationFrame, objects);
ObjectGraph.addProperty(objects, args);

final Deque<Object> stack = new ArrayDeque<>(objects);
shareObjects(stack);
Expand Down

0 comments on commit 9f026cb

Please sign in to comment.