Repository: mesos Updated Branches: refs/heads/master 4809d161e -> 5d0b5fdb5
Fix memory corruption in AbstractState JNI bindings. MESOS-2161. Review: https://reviews.apache.org/r/32152 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5d0b5fdb Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5d0b5fdb Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5d0b5fdb Branch: refs/heads/master Commit: 5d0b5fdb5d8d78b44537cb01916263a3769b5d7d Parents: 9706bb0 Author: Joris Van Remoortere <[email protected]> Authored: Sun Mar 29 12:20:24 2015 -0700 Committer: Benjamin Hindman <[email protected]> Committed: Sun Mar 29 12:44:36 2015 -0700 ---------------------------------------------------------------------- .../org_apache_mesos_state_AbstractState.cpp | 514 +++++++++++++++++++ .../org/apache/mesos/state/AbstractState.java | 165 +++++- 2 files changed, 678 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/5d0b5fdb/src/java/jni/org_apache_mesos_state_AbstractState.cpp ---------------------------------------------------------------------- diff --git a/src/java/jni/org_apache_mesos_state_AbstractState.cpp b/src/java/jni/org_apache_mesos_state_AbstractState.cpp index 1accc8a..2be377c 100644 --- a/src/java/jni/org_apache_mesos_state_AbstractState.cpp +++ b/src/java/jni/org_apache_mesos_state_AbstractState.cpp @@ -23,6 +23,16 @@ using std::string; extern "C" { +// TODO(jmlvanre): Deprecate the JNI functions that are in the AbstractState +// scope that we have replaced with the ones in the names classes 'FetchFuture', +// 'StoreFuture', 'ExpungeFuture', and 'NamesFuture'. (MESOS-2161). The +// anonymous futures that used these function accidentally captured the 'thiz' +// for the 'AbstractState' class, which was not intended and caused the C++ +// Future to be prematurely deleted as a result of the anonymous Future getting +// garbaged collected by the JVM and invoking the finalizer which deleted the +// C++ Future. The intent was to capture the 'thiz' for the 'Future'. This is +// done correctly by using the named inner classes. + /* * Class: org_apache_mesos_state_AbstractState * Method: finalize @@ -228,6 +238,132 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState__1_1fetch_1fina /* + * Class: org_apache_mesos_state_AbstractState$FetchFuture + * Method: cancel + * Signature: (Z)Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024FetchFuture_cancel + (JNIEnv* env, jobject thiz, jboolean mayInterruptIfRunning) +{ + if (mayInterruptIfRunning) { + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1fetch_1cancel( + env, + thiz, + jfuture); + } + + return false; // Should not interrupt and already running (or finished). +} + + +/* + * Class: org_apache_mesos_state_AbstractState$FetchFuture + * Method: is_cancelled + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024FetchFuture_is_1cancelled + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1fetch_1is_1cancelled( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$FetchFuture + * Method: is_done + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024FetchFuture_is_1done + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1fetch_1is_1done( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$FetchFuture + * Method: get + * Signature: ()Lorg/apache/mesos/state/Variable; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024FetchFuture_get + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1fetch_1get( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$FetchFuture + * Method: get_timeout + * Signature: (JLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024FetchFuture_get_1timeout + (JNIEnv* env, jobject thiz, jlong jtimeout, jobject junit) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1fetch_1get_1timeout( + env, + thiz, + jfuture, + jtimeout, + junit); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$FetchFuture + * Method: finalize + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState_00024FetchFuture_finalize + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + Java_org_apache_mesos_state_AbstractState__1_1fetch_1finalize( + env, + thiz, + jfuture); +} + + +/* * Class: org_apache_mesos_state_AbstractState * Method: __store * Signature: (Lorg/apache/mesos/state/Variable;)J @@ -422,6 +558,132 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState__1_1store_1fina /* + * Class: org_apache_mesos_state_AbstractState$StoreFuture + * Method: cancel + * Signature: (Z)Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024StoreFuture_cancel + (JNIEnv* env, jobject thiz, jboolean mayInterruptIfRunning) +{ + if (mayInterruptIfRunning) { + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1store_1cancel( + env, + thiz, + jfuture); + } + + return false; // Should not interrupt and already running (or finished). +} + + +/* + * Class: org_apache_mesos_state_AbstractState$StoreFuture + * Method: is_cancelled + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024StoreFuture_is_1cancelled + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1store_1is_1cancelled( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$StoreFuture + * Method: is_done + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024StoreFuture_is_1done + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1store_1is_1done( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$StoreFuture + * Method: get + * Signature: ()Lorg/apache/mesos/state/Variable; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024StoreFuture_get + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1store_1get( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$StoreFuture + * Method: get_timeout + * Signature: (JLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024StoreFuture_get_1timeout + (JNIEnv* env, jobject thiz, jlong jtimeout, jobject junit) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1store_1get_1timeout( + env, + thiz, + jfuture, + jtimeout, + junit); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$StoreFuture + * Method: finalize + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState_00024StoreFuture_finalize + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + Java_org_apache_mesos_state_AbstractState__1_1store_1finalize( + env, + thiz, + jfuture); +} + + +/* * Class: org_apache_mesos_state_AbstractState * Method: __expunge * Signature: (Lorg/apache/mesos/state/Variable;)J @@ -601,6 +863,132 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState__1_1expunge_1fi /* + * Class: org_apache_mesos_state_AbstractState$ExpungeFuture + * Method: cancel + * Signature: (Z)Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024ExpungeFuture_cancel + (JNIEnv* env, jobject thiz, jboolean mayInterruptIfRunning) +{ + if (mayInterruptIfRunning) { + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1expunge_1cancel( + env, + thiz, + jfuture); + } + + return false; // Should not interrupt and already running (or finished). +} + + +/* + * Class: org_apache_mesos_state_AbstractState$ExpungeFuture + * Method: is_cancelled + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024ExpungeFuture_is_1cancelled + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1expunge_1is_1cancelled( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$ExpungeFuture + * Method: is_done + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024ExpungeFuture_is_1done + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1expunge_1is_1done( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$ExpungeFuture + * Method: __get + * Signature: ()Ljava/lang/Boolean; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024ExpungeFuture_get + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1expunge_1get( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$ExpungeFuture + * Method: get_timeout + * Signature: (JLjava/util/concurrent/TimeUnit;)Ljava/lang/Boolean; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024ExpungeFuture_get_1timeout + (JNIEnv* env, jobject thiz, jlong jtimeout, jobject junit) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1expunge_1get_1timeout( + env, + thiz, + jfuture, + jtimeout, + junit); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$ExpungeFuture + * Method: finalize + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState_00024ExpungeFuture_finalize + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + Java_org_apache_mesos_state_AbstractState__1_1expunge_1finalize( + env, + thiz, + jfuture); +} + + +/* * Class: org_apache_mesos_state_AbstractState * Method: __names * Signature: ()J @@ -792,4 +1180,130 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState__1_1names_1fina delete future; } + +/* + * Class: org_apache_mesos_state_AbstractState$NamesFuture + * Method: cancel + * Signature: (Z)Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024NamesFuture_cancel + (JNIEnv* env, jobject thiz, jboolean mayInterruptIfRunning) +{ + if (mayInterruptIfRunning) { + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1names_1cancel( + env, + thiz, + jfuture); + } + + return false; // Should not interrupt and already running (or finished). +} + + +/* + * Class: org_apache_mesos_state_AbstractState$NamesFuture + * Method: is_cancelled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024NamesFuture_is_1cancelled + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1names_1is_1cancelled( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$NamesFuture + * Method: is_done + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_AbstractState_00024NamesFuture_is_1done + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1names_1is_1done( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$NamesFuture + * Method: get + * Signature: ()Ljava/util/Iterator; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024NamesFuture_get + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1names_1get( + env, + thiz, + jfuture); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$NamesFuture + * Method: get_timeout + * Signature: (JLjava/util/concurrent/TimeUnit;)Ljava/util/Iterator; + */ +JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState_00024NamesFuture_get_1timeout + (JNIEnv* env, jobject thiz, jlong jtimeout, jobject junit) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + return Java_org_apache_mesos_state_AbstractState__1_1names_1get_1timeout( + env, + thiz, + jfuture, + jtimeout, + junit); +} + + +/* + * Class: org_apache_mesos_state_AbstractState$NamesFuture + * Method: finalize + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_apache_mesos_state_AbstractState_00024NamesFuture_finalize + (JNIEnv* env, jobject thiz) +{ + static jclass clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(thiz)); + static jfieldID field = env->GetFieldID(clazz, "future", "J"); + jlong jfuture = env->GetLongField(thiz, field); + + // See TODO at top of file for why we proxy this call. + Java_org_apache_mesos_state_AbstractState__1_1names_1finalize( + env, + thiz, + jfuture); +} + } // extern "C" { http://git-wip-us.apache.org/repos/asf/mesos/blob/5d0b5fdb/src/java/src/org/apache/mesos/state/AbstractState.java ---------------------------------------------------------------------- diff --git a/src/java/src/org/apache/mesos/state/AbstractState.java b/src/java/src/org/apache/mesos/state/AbstractState.java index c66bf05..6514954 100644 --- a/src/java/src/org/apache/mesos/state/AbstractState.java +++ b/src/java/src/org/apache/mesos/state/AbstractState.java @@ -38,6 +38,11 @@ public abstract class AbstractState implements State { @Override public Future<Variable> fetch(final String name) { + if (!MesosNativeLibrary.version().before(MESOS_2161_JIRA_FIX_VERSION)) { + return new FetchFuture(name); + } + + // TODO(jmlvanre): Deprecate anonymous future in 0.24 (MESOS-2161). final long future = __fetch(name); // Asynchronously start the operation. return new Future<Variable>() { @Override @@ -78,6 +83,11 @@ public abstract class AbstractState implements State { @Override public Future<Variable> store(Variable variable) { + if (!MesosNativeLibrary.version().before(MESOS_2161_JIRA_FIX_VERSION)) { + return new StoreFuture(variable); + } + + // TODO(jmlvanre): Deprecate anonymous future in 0.24 (MESOS-2161). final long future = __store(variable); // Asynchronously start the operation. return new Future<Variable>() { @Override @@ -118,6 +128,11 @@ public abstract class AbstractState implements State { @Override public Future<Boolean> expunge(Variable variable) { + if (!MesosNativeLibrary.version().before(MESOS_2161_JIRA_FIX_VERSION)) { + return new ExpungeFuture(variable); + } + + // TODO(jmlvanre): Deprecate anonymous future in 0.24 (MESOS-2161). final long future = __expunge(variable); // Asynchronously start the operation. return new Future<Boolean>() { @Override @@ -157,6 +172,11 @@ public abstract class AbstractState implements State { } public Future<Iterator<String>> names() { + if (!MesosNativeLibrary.version().before(MESOS_2161_JIRA_FIX_VERSION)) { + return new NamesFuture(); + } + + // TODO(jmlvanre): Deprecate anonymous future in 0.24 (MESOS-2161). final long future = __names(); // Asynchronously start the operation. return new Future<Iterator<String>>() { @Override @@ -198,8 +218,46 @@ public abstract class AbstractState implements State { protected native void finalize(); - // Native implementations of 'fetch', 'store', 'expunge', and 'names'. + // Native implementations of 'fetch', 'store', 'expunge', and 'names'. We wrap + // them in classes to carry the java references correctly through the JNI + // bindings (MESOS-2161). The native functions in AbstractState will be + // deprecated in 0.24. + + private class FetchFuture implements Future<Variable> { + + public FetchFuture(String name) { + future = __fetch(name); + } + + @Override + public native boolean cancel(boolean mayInterruptIfRunning); + + @Override + public native boolean isCancelled(); + + @Override + public native boolean isDone(); + + @Override + public native Variable get() + throws InterruptedException, ExecutionException; + + @Override + public native Variable get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException; + + @Override + protected native void finalize(); + + private long future; + } + private native long __fetch(String name); + + // TODO(jmlvanre): Deprecate below functions in 0.24 because we can't track + // the java object references correctly. (MESOS-2161). The above 'FetchFuture' + // class fixes this bug. We leave the below functions for backwards + // compatibility. private native boolean __fetch_cancel(long future); private native boolean __fetch_is_cancelled(long future); private native boolean __fetch_is_done(long future); @@ -208,7 +266,41 @@ public abstract class AbstractState implements State { long future, long timeout, TimeUnit unit); private native void __fetch_finalize(long future); + private class StoreFuture implements Future<Variable> { + + public StoreFuture(Variable variable) { + future = __store(variable); + } + + @Override + public native boolean cancel(boolean mayInterruptIfRunning); + + @Override + public native boolean isCancelled(); + + @Override + public native boolean isDone(); + + @Override + public native Variable get() + throws InterruptedException, ExecutionException; + + @Override + public native Variable get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException; + + @Override + protected native void finalize(); + + private long future; + } + private native long __store(Variable variable); + + // TODO(jmlvanre): Deprecate below functions in 0.24 because we can't track + // the java object references correctly. (MESOS-2161). The above 'StoreFuture' + // class fixes this bug. We leave the below functions for backwards + // compatibility. private native boolean __store_cancel(long future); private native boolean __store_is_cancelled(long future); private native boolean __store_is_done(long future); @@ -217,7 +309,41 @@ public abstract class AbstractState implements State { long future, long timeout, TimeUnit unit); private native void __store_finalize(long future); + private class ExpungeFuture implements Future<Boolean> { + + public ExpungeFuture(Variable variable) { + future = __expunge(variable); + } + + @Override + public native boolean cancel(boolean mayInterruptIfRunning); + + @Override + public native boolean isCancelled(); + + @Override + public native boolean isDone(); + + @Override + public native Boolean get() + throws InterruptedException, ExecutionException; + + @Override + public native Boolean get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException; + + @Override + protected native void finalize(); + + private long future; + } + private native long __expunge(Variable variable); + + // TODO(jmlvanre): Deprecate below functions in 0.24 because we can't track + // the java object references correctly. (MESOS-2161). The above + // 'ExpungeFuture' class fixes this bug. We leave the below functions for + // backwards compatibility. private native boolean __expunge_cancel(long future); private native boolean __expunge_is_cancelled(long future); private native boolean __expunge_is_done(long future); @@ -226,7 +352,41 @@ public abstract class AbstractState implements State { long future, long timeout, TimeUnit unit); private native void __expunge_finalize(long future); + private class NamesFuture implements Future<Iterator<String>> { + + public NamesFuture() { + future = __names(); + } + + @Override + public native boolean cancel(boolean mayInterruptIfRunning); + + @Override + public native boolean isCancelled(); + + @Override + public native boolean isDone(); + + @Override + public native Iterator<String> get() + throws InterruptedException, ExecutionException; + + @Override + public native Iterator<String> get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException; + + @Override + protected native void finalize(); + + private long future; + } + private native long __names(); + + // TODO(jmlvanre): Deprecate below functions in 0.24 because we can't track + // the java object references correctly. (MESOS-2161). The above 'NamesFuture' + // class fixes this bug. We leave the below functions for backwards + // compatibility. private native boolean __names_cancel(long future); private native boolean __names_is_cancelled(long future); private native boolean __names_is_done(long future); @@ -237,4 +397,7 @@ public abstract class AbstractState implements State { private long __storage; private long __state; + + private final static MesosNativeLibrary.Version MESOS_2161_JIRA_FIX_VERSION = + new MesosNativeLibrary.Version(0, 22, 1); }
