From c201eac291682a9bdb9ca2790403084b4f36da76 Mon Sep 17 00:00:00 2001 From: Mariot Chauvin Date: Tue, 10 Feb 2015 15:15:29 +0000 Subject: SI-8362: AbstractPromise extends AtomicReference To avoid `sun.misc.Unsafe`, which is not supported on Google App Engine. Deprecate `AbstractPromise` --> extend `j.u.c.atomic.AtomicReference` directly. `AtomicReference.compareAndSet()` should also provide better performance on HotSpot, which compiles it down to the machine's CAS instruction. The binary incompatible change is ok because it's in an internal package. I can't think of any real issue with adding a superclass (which contributes only final methods) to a class in an implementation package (as long as those methods were not introduced in any illicit subclasses of said class). Instead of changing `DefaultPromise`'s super class, let's be more conservative, and do it closest to the source. This is both clearer and more focussed, leaving those subclasses of AbstractPromise we never heard of unaffected. Genesis of the commit: since the work on `Future` performance, `AbstractPromise` is using `Unsafe`, breaking the ability for `Future` to be executed on GAE. At that time, viktorklang suggested to implement a fallback in case `Unsafe` is not available. carey proposed an implementation, and mchv submitted a patch, which was refined by adriaanm. --- .../scala/concurrent/impl/AbstractPromise.java | 37 ++++------------------ 1 file changed, 7 insertions(+), 30 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/concurrent/impl/AbstractPromise.java b/src/library/scala/concurrent/impl/AbstractPromise.java index b8165b6cde..c2520a1692 100644 --- a/src/library/scala/concurrent/impl/AbstractPromise.java +++ b/src/library/scala/concurrent/impl/AbstractPromise.java @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2003-2015, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -8,33 +8,10 @@ package scala.concurrent.impl; +import java.util.concurrent.atomic.AtomicReference; -import scala.concurrent.util.Unsafe; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - - - -abstract class AbstractPromise { - private volatile Object _ref; - - final static long _refoffset; - - static { - try { - _refoffset = Unsafe.instance.objectFieldOffset(AbstractPromise.class.getDeclaredField("_ref")); - } catch (Throwable t) { - throw new ExceptionInInitializerError(t); - } - } - - protected final boolean updateState(Object oldState, Object newState) { - return Unsafe.instance.compareAndSwapObject(this, _refoffset, oldState, newState); - } - - protected final Object getState() { - return _ref; - } - - protected final static AtomicReferenceFieldUpdater updater = - AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref"); -} \ No newline at end of file +@Deprecated // Since 2.11.8. Extend java.util.concurrent.atomic.AtomicReference instead. +abstract class AbstractPromise extends AtomicReference { + protected final boolean updateState(Object oldState, Object newState) { return compareAndSet(oldState, newState); } + protected final Object getState() { return get(); } +} -- cgit v1.2.3