Skip to content

Commit 50191c9

Browse files
committed
Correctly claim and release the c ext mutex when required.
PullRequest: truffleruby/743
2 parents 32c39f8 + 976120d commit 50191c9

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

lib/truffle/truffle/cext.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,10 @@ def rb_thread_create(fn, args)
15921592
end
15931593
end
15941594

1595+
def rb_thread_call_with_gvl(function, data)
1596+
Truffle.invoke_primitive(:interop_call_c_with_mutex, function, [data])
1597+
end
1598+
15951599
def rb_thread_call_without_gvl(function, data1, unblock, data2)
15961600
if unblock
15971601
unblocker = -> {

src/main/c/cext/ruby.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2526,7 +2526,7 @@ void rb_gc(void) {
25262526
// Threads
25272527

25282528
void *rb_thread_call_with_gvl(gvl_call function, void *data1) {
2529-
return function(data1);
2529+
return polyglot_invoke(RUBY_CEXT, "rb_thread_call_with_gvl", function, data1);
25302530
}
25312531

25322532
void *rb_thread_call_without_gvl(gvl_call function, void *data1, rb_unblock_function_t *unblock_function, void *data2) {

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,23 @@ public abstract static class CallCWithMutexNode extends PrimitiveArrayArgumentsN
121121
public Object callCWithMutex(TruffleObject receiver, DynamicObject argsArray,
122122
@Cached("create()") ArrayToObjectArrayNode arrayToObjectArrayNode,
123123
@Cached("EXECUTE.createNode()") Node executeNode,
124-
@Cached("create()") BranchProfile exceptionProfile) {
124+
@Cached("create()") BranchProfile exceptionProfile,
125+
@Cached("createBinaryProfile()") ConditionProfile ownedProfile) {
125126
final Object[] args = arrayToObjectArrayNode.executeToObjectArray(argsArray);
126127

127128
if (getContext().getOptions().CEXT_LOCK) {
128129
final ReentrantLock lock = getContext().getCExtensionsLock();
130+
boolean owned = lock.isHeldByCurrentThread();
129131

130-
MutexOperations.lockInternal(getContext(), lock, this);
131-
try {
132+
if (ownedProfile.profile(!owned)) {
133+
MutexOperations.lockInternal(getContext(), lock, this);
134+
try {
135+
return execute(receiver, args, executeNode, exceptionProfile);
136+
} finally {
137+
MutexOperations.unlockInternal(lock);
138+
}
139+
} else {
132140
return execute(receiver, args, executeNode, exceptionProfile);
133-
} finally {
134-
MutexOperations.unlockInternal(lock);
135141
}
136142
} else {
137143
return execute(receiver, args, executeNode, exceptionProfile);
@@ -158,17 +164,23 @@ public abstract static class CallCWithoutMutexNode extends PrimitiveArrayArgumen
158164
public Object callCWithoutMutex(TruffleObject receiver, DynamicObject argsArray,
159165
@Cached("create()") ArrayToObjectArrayNode arrayToObjectArrayNode,
160166
@Cached("EXECUTE.createNode()") Node executeNode,
161-
@Cached("create()") BranchProfile exceptionProfile) {
167+
@Cached("create()") BranchProfile exceptionProfile,
168+
@Cached("createBinaryProfile()") ConditionProfile ownedProfile) {
162169
final Object[] args = arrayToObjectArrayNode.executeToObjectArray(argsArray);
163170

164171
if (getContext().getOptions().CEXT_LOCK) {
165172
final ReentrantLock lock = getContext().getCExtensionsLock();
173+
boolean owned = lock.isHeldByCurrentThread();
166174

167-
MutexOperations.unlockInternal(lock);
168-
try {
175+
if (ownedProfile.profile(owned)) {
176+
MutexOperations.unlockInternal(lock);
177+
try {
178+
return execute(receiver, args, executeNode, exceptionProfile);
179+
} finally {
180+
MutexOperations.lockInternal(getContext(), lock, this);
181+
}
182+
} else {
169183
return execute(receiver, args, executeNode, exceptionProfile);
170-
} finally {
171-
MutexOperations.lockInternal(getContext(), lock, this);
172184
}
173185
} else {
174186
return execute(receiver, args, executeNode, exceptionProfile);

0 commit comments

Comments
 (0)