diff --git a/README.md b/README.md index e0596ec..578603c 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ task { "world" } and task { "Hello" } success { Please refer to the [Kovenant](http://kovenant.komponents.nl) site for API usage and more. ## Getting started -Build against Kotlin: `1.0.1`. +Build against Kotlin: `1.0.1-1`. Source and target compatibility is `1.6` ###Gradle ```groovy dependencies { - compile 'nl.komponents.kovenant:kovenant:3.2.0' + compile 'nl.komponents.kovenant:kovenant:3.2.1' } ``` @@ -32,7 +32,7 @@ dependencies { nl.komponents.kovenant kovenant - 3.2.0 + 3.2.1 ``` diff --git a/build.gradle b/build.gradle index f8f0a03..af9ce96 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ */ buildscript { - ext.kotlinVersion = '1.0.1' + ext.kotlinVersion = '1.0.1-1' ext.extraConfVersion = '2.2.+' repositories { @@ -39,7 +39,7 @@ buildscript { allprojects { ext { - appVersion = '3.2.0' + appVersion = '3.2.1' appGroup = 'nl.komponents.kovenant' diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index a2315b6..81068e0 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -3,6 +3,12 @@ Changelog of Kovenant. Complying to [Semantic Versioning](http://semver.org). Please refer to [roadmap](roadmap.md) for upcoming releases. +##v3.2.1 + +**core** + +* [KOV-78](http://issues.komponents.nl/youtrack/issue/KOV-78) Support android with api level set to 15 + ##v3.2.0 **core** diff --git a/docs/docs/index.md b/docs/docs/index.md index 7d8492a..cfa8180 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -25,13 +25,13 @@ Developed with the following [goals](misc/goals.md) in mind. * **Dependency free**: when not counting kotlin std ## Getting started -Build against Kotlin: `1.0.1`. +Build against Kotlin: `1.0.1-1`. Source and target compatibility is `1.6` ###Gradle ```groovy dependencies { - compile 'nl.komponents.kovenant:kovenant:3.2.0' + compile 'nl.komponents.kovenant:kovenant:3.2.1' } ``` @@ -40,7 +40,7 @@ dependencies { nl.komponents.kovenant kovenant - 3.2.0 + 3.2.1 ``` diff --git a/projects/core/src/main/kotlin/cas-jvm.kt b/projects/core/src/main/kotlin/cas-jvm.kt index ebcf3c2..f835306 100644 --- a/projects/core/src/main/kotlin/cas-jvm.kt +++ b/projects/core/src/main/kotlin/cas-jvm.kt @@ -1,6 +1,26 @@ +/* + * Copyright (c) 2016 Mark Platvoet + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * THE SOFTWARE. + */ + package nl.komponents.kovenant.unsafe -import sun.misc.Unsafe import java.util.concurrent.atomic.AtomicReferenceFieldUpdater import kotlin.reflect.KClass @@ -29,23 +49,54 @@ class UnsafeAtomicReferenceFieldUpdater(targetClass: KClass override fun weakCompareAndSet(target: C, expected: V?, update: V?): Boolean = compareAndSet(target, expected, update) } +private val noUnsafeMarker = Any() +private @Volatile var unsafeInstance: Any? = null fun hasUnsafe(): Boolean { - try { - Class.forName("sun.misc.Unsafe") - return true - } catch(e: ClassNotFoundException) { - return false + if (unsafeInstance == null) { + loadUnsafe() } + return unsafeInstance != noUnsafeMarker } -private fun getUnsafe(): Unsafe { +private fun loadUnsafe() { try { - val field = Unsafe::class.java.getDeclaredField("theUnsafe"); - field.isAccessible = true; - return field.get(null) as Unsafe; + val clazz = Class.forName("sun.misc.Unsafe") + + clazz.tryGetStaticField("theUnsafe") { + unsafeInstance = it ?: noUnsafeMarker + return + } + + //KOV-78: Name on old dalvik implementations + clazz.tryGetStaticField("THE_ONE") { + unsafeInstance = it ?: noUnsafeMarker + return + } + } catch(e: Exception) { + //ignore + } + unsafeInstance = noUnsafeMarker +} +private inline fun Class<*>.tryGetStaticField(name: String, onFound: (Any?) -> Unit) { + try { + val field = getDeclaredField(name) + field.isAccessible = true + val fieldValue = field.get(null) + onFound(fieldValue) } catch (e: Exception) { - throw RuntimeException("unsafe doesn't exist or is not accessible") + //ignore + } +} + +private fun getUnsafe(): sun.misc.Unsafe { + if (unsafeInstance == null) { + loadUnsafe() + } + if (unsafeInstance != noUnsafeMarker) { + return unsafeInstance as sun.misc.Unsafe } + + throw RuntimeException("unsafe doesn't exist or is not accessible") } \ No newline at end of file diff --git a/projects/rx/rx.gradle b/projects/rx/rx.gradle index a1d8fdc..09cdc54 100644 --- a/projects/rx/rx.gradle +++ b/projects/rx/rx.gradle @@ -24,5 +24,5 @@ project.description = "Add Promise support to Rx" dependencies { compile project(':kovenant-core') - compile 'io.reactivex:rxjava:1.1.1' + compile 'io.reactivex:rxjava:1.1.2' } \ No newline at end of file