Skip to content

Commit 00b1ba9

Browse files
committed
Do not use deprecated constant
1 parent fcffb27 commit 00b1ba9

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

ext/com/concurrent_ruby/ext/SynchronizationLibrary.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
package com.concurrent_ruby.ext;
22

3-
import java.io.IOException;
4-
53
import org.jruby.Ruby;
4+
import org.jruby.RubyBasicObject;
65
import org.jruby.RubyClass;
76
import org.jruby.RubyModule;
87
import org.jruby.RubyObject;
9-
import org.jruby.RubyBasicObject;
108
import org.jruby.anno.JRubyClass;
119
import org.jruby.anno.JRubyMethod;
10+
import org.jruby.runtime.Block;
1211
import org.jruby.runtime.ObjectAllocator;
12+
import org.jruby.runtime.ThreadContext;
13+
import org.jruby.runtime.Visibility;
1314
import org.jruby.runtime.builtin.IRubyObject;
1415
import org.jruby.runtime.load.Library;
15-
import org.jruby.runtime.Block;
16-
import org.jruby.runtime.Visibility;
17-
import org.jruby.runtime.ThreadContext;
1816
import org.jruby.util.unsafe.UnsafeHolder;
1917

18+
import java.io.IOException;
19+
import java.lang.reflect.Method;
20+
2021
public class SynchronizationLibrary implements Library {
2122

2223
private static final ObjectAllocator JRUBY_OBJECT_ALLOCATOR = new ObjectAllocator() {
@@ -84,10 +85,28 @@ private RubyClass defineClass(Ruby runtime, RubyModule namespace, String parentN
8485
// - writes depend on UnsafeHolder.U, null -> SynchronizedVariableAccessor, !null -> StampedVariableAccessor
8586
// SynchronizedVariableAccessor wraps with synchronized block, StampedVariableAccessor uses fullFence or
8687
// volatilePut
88+
// TODO (pitr 16-Sep-2015): what do we do in Java 9 ?
8789

8890
// module JRubyAttrVolatile
8991
public static class JRubyAttrVolatile {
9092

93+
private static boolean supportsFences() {
94+
if(UnsafeHolder.U == null) {
95+
return false;
96+
} else {
97+
try {
98+
Method m = UnsafeHolder.U.getClass().getDeclaredMethod("fullFence", new Class[0]);
99+
if(m != null) {
100+
return true;
101+
}
102+
} catch (Exception var1) {
103+
// nothing
104+
}
105+
106+
return false;
107+
}
108+
}
109+
91110
// volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic
92111
// on volatile fields. any volatile field could have been used but using the thread context is an
93112
// attempt to avoid code elimination.
@@ -96,9 +115,10 @@ public static class JRubyAttrVolatile {
96115
@JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC)
97116
public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject self) {
98117
// Prevent reordering of ivar writes with publication of this instance
99-
if (UnsafeHolder.U == null || !UnsafeHolder.SUPPORTS_FENCES) {
118+
if (!supportsFences()) {
100119
// Assuming that following volatile read and write is not eliminated it simulates fullFence.
101120
// If it's eliminated it'll cause problems only on non-x86 platforms.
121+
// http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding
102122
final ThreadContext oldContext = threadContext;
103123
threadContext = context;
104124
} else {
@@ -110,7 +130,7 @@ public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject s
110130
@JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC)
111131
public static IRubyObject instanceVariableGetVolatile(ThreadContext context, IRubyObject self, IRubyObject name) {
112132
// Ensure we ses latest value with loadFence
113-
if (UnsafeHolder.U == null || !UnsafeHolder.SUPPORTS_FENCES) {
133+
if (!supportsFences()) {
114134
// piggybacking on volatile read, simulating loadFence
115135
final ThreadContext oldContext = threadContext;
116136
return ((RubyBasicObject)self).instance_variable_get(context, name);
@@ -123,7 +143,7 @@ public static IRubyObject instanceVariableGetVolatile(ThreadContext context, IRu
123143
@JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC)
124144
public static IRubyObject InstanceVariableSetVolatile(ThreadContext context, IRubyObject self, IRubyObject name, IRubyObject value) {
125145
// Ensure we make last update visible
126-
if (UnsafeHolder.U == null || !UnsafeHolder.SUPPORTS_FENCES) {
146+
if (!supportsFences()) {
127147
// piggybacking on volatile write, simulating storeFence
128148
final IRubyObject result = ((RubyBasicObject)self).instance_variable_set(name, value);
129149
threadContext = context;

0 commit comments

Comments
 (0)