Skip to content

Commit 9f026cb

Browse files
committed
The arguments of Thread.new need to be marked as shared between multiple threads
* See #3179 (comment)
1 parent 8b4a7b3 commit 9f026cb

File tree

4 files changed

+34
-3
lines changed

4 files changed

+34
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Bug fixes:
1313
* Fix some C API functions which were failing when called with Ruby values represented as Java primitives (#3352, @eregon).
1414
* Fix `IO.select([io], nil, [io])` on macOS, it was hanging due to a bug in macOS `poll(2)` (#3346, @eregon, @andrykonchin).
1515
* Run context cleanup such as showing the output of tools when `SignalException` and `Interrupt` escape (@eregon).
16+
* The arguments of `Thread.new(*args, &block)` need to be marked as shared between multiple threads (#3179, @eregon).
1617

1718
Compatibility:
1819

spec/truffle/thread_safe_objects_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,35 @@ def wb; @wb; end
293293
shared?(new_hash).should == true
294294
end
295295

296+
describe "Thread.new's" do
297+
it "block" do
298+
obj = Object.new
299+
t = Thread.new { sleep }
300+
begin
301+
shared?(obj).should == true
302+
ensure
303+
t.kill
304+
t.join
305+
end
306+
end
307+
308+
# avoid capturing local variables in the spec example below
309+
thread_body = proc { sleep }
310+
311+
it "arguments" do
312+
obj1 = Object.new
313+
obj2 = Object.new
314+
t = Thread.new(obj1, obj2, &thread_body)
315+
begin
316+
shared?(obj1).should == true
317+
shared?(obj2).should == true
318+
ensure
319+
t.kill
320+
t.join
321+
end
322+
end
323+
end
324+
296325
it "Fiber local variables which share the value (since they can be accessed from other threads)" do
297326
require 'fiber'
298327
# Create a new Thread to make sure the root Fiber is shared as expected

src/main/java/org/truffleruby/core/thread/ThreadNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ private Object init(RubyThread thread, RubyProc block, ArgumentsDescriptor descr
433433

434434
if (getLanguage().options.SHARED_OBJECTS_ENABLED) {
435435
getContext().getThreadManager().startSharing(thread, sharingReason);
436-
SharedObjects.shareDeclarationFrame(getLanguage(), block, info);
436+
SharedObjects.shareBlockAndArguments(getLanguage(), block, args, info);
437437
}
438438

439439
getContext().getThreadManager().initialize(

src/main/java/org/truffleruby/language/objects/shared/SharedObjects.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,14 @@ private static void shareContextRoots(RubyLanguage language, RubyContext context
8282
}
8383
}
8484

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

9090
final Set<Object> objects = ObjectGraph.newObjectSet();
9191
ObjectGraph.getObjectsInFrame(block.declarationFrame, objects);
92+
ObjectGraph.addProperty(objects, args);
9293

9394
final Deque<Object> stack = new ArrayDeque<>(objects);
9495
shareObjects(stack);

0 commit comments

Comments
 (0)