Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2491,6 +2491,8 @@ int hadoopRzOptionsSetByteBufferPool(
JNIEnv *env;
jthrowable jthr;
jobject byteBufferPool = NULL;
jobject globalByteBufferPool = NULL;
int ret;

env = getJNIEnv();
if (!env) {
Expand All @@ -2507,15 +2509,37 @@ int hadoopRzOptionsSetByteBufferPool(
if (jthr) {
printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"hadoopRzOptionsSetByteBufferPool(className=%s): ", className);
errno = EINVAL;
return -1;
ret = EINVAL;
goto done;
}
}
if (opts->byteBufferPool) {
// Delete any previous ByteBufferPool we had.
// Only set opts->byteBufferPool if creating a global reference is
// successful
globalByteBufferPool = (*env)->NewGlobalRef(env, byteBufferPool);
if (!globalByteBufferPool) {
printPendingExceptionAndFree(env, PRINT_EXC_ALL,
"hadoopRzOptionsSetByteBufferPool(className=%s): ",
className);
ret = EINVAL;
goto done;
}
// Delete any previous ByteBufferPool we had before setting a new one.
if (opts->byteBufferPool) {
(*env)->DeleteGlobalRef(env, opts->byteBufferPool);
}
opts->byteBufferPool = globalByteBufferPool;
} else if (opts->byteBufferPool) {
// If the specified className is NULL, delete any previous
// ByteBufferPool we had.
(*env)->DeleteGlobalRef(env, opts->byteBufferPool);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to also set it back to null, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah done.

opts->byteBufferPool = NULL;
}
ret = 0;
done:
destroyLocalReference(env, byteBufferPool);
if (ret) {
errno = ret;
return -1;
}
opts->byteBufferPool = (*env)->NewGlobalRef(env, byteBufferPool);
return 0;
}

Expand Down Expand Up @@ -2570,8 +2594,7 @@ static jthrowable hadoopRzOptionsGetEnumSet(JNIEnv *env,
} else {
jclass clazz = (*env)->FindClass(env, READ_OPTION);
if (!clazz) {
jthr = newRuntimeError(env, "failed "
"to find class for %s", READ_OPTION);
jthr = getPendingExceptionAndClear(env);
goto done;
}
jthr = invokeMethod(env, &jVal, STATIC, NULL,
Expand Down Expand Up @@ -2697,6 +2720,7 @@ static int translateZCRException(JNIEnv *env, jthrowable exc)
}
if (!strcmp(className, "java.lang.UnsupportedOperationException")) {
ret = EPROTONOSUPPORT;
destroyLocalReference(env, exc);
goto done;
}
ret = printExceptionAndFree(env, exc, PRINT_EXC_ALL,
Expand Down Expand Up @@ -2896,8 +2920,9 @@ hdfsGetHosts(hdfsFS fs, const char *path, tOffset start, tOffset length)
for (i = 0; i < jNumFileBlocks; ++i) {
jFileBlock =
(*env)->GetObjectArrayElement(env, jBlockLocations, i);
if (!jFileBlock) {
ret = printPendingExceptionAndFree(env, PRINT_EXC_ALL,
jthr = (*env)->ExceptionOccurred(env);
if (jthr || !jFileBlock) {
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"hdfsGetHosts(path=%s, start=%"PRId64", length=%"PRId64"):"
"GetObjectArrayElement(%d)", path, start, length, i);
goto done;
Expand Down Expand Up @@ -2930,8 +2955,9 @@ hdfsGetHosts(hdfsFS fs, const char *path, tOffset start, tOffset length)
//Now parse each hostname
for (j = 0; j < jNumBlockHosts; ++j) {
jHost = (*env)->GetObjectArrayElement(env, jFileBlockHosts, j);
if (!jHost) {
ret = printPendingExceptionAndFree(env, PRINT_EXC_ALL,
jthr = (*env)->ExceptionOccurred(env);
if (jthr || !jHost) {
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"hdfsGetHosts(path=%s, start=%"PRId64", length=%"PRId64"): "
"NewByteArray", path, start, length);
goto done;
Expand Down Expand Up @@ -3419,8 +3445,9 @@ hdfsFileInfo* hdfsListDirectory(hdfsFS fs, const char *path, int *numEntries)
//Save path information in pathList
for (i=0; i < jPathListSize; ++i) {
tmpStat = (*env)->GetObjectArrayElement(env, jPathList, i);
if (!tmpStat) {
ret = printPendingExceptionAndFree(env, PRINT_EXC_ALL,
jthr = (*env)->ExceptionOccurred(env);
if (jthr || !tmpStat) {
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"hdfsListDirectory(%s): GetObjectArrayElement(%d out of %d)",
path, i, jPathListSize);
goto done;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ jthrowable classNameOfObject(jobject jobj, JNIEnv *env, char **name)
goto done;
}
str = (*env)->CallObjectMethod(env, cls, mid);
jthr = (*env)->ExceptionOccurred(env);
if (jthr) {
(*env)->ExceptionClear(env);
goto done;
}
if (str == NULL) {
jthr = getPendingExceptionAndClear(env);
goto done;
Expand Down Expand Up @@ -644,8 +649,7 @@ jthrowable fetchEnumInstance(JNIEnv *env, const char *className,

clazz = (*env)->FindClass(env, className);
if (!clazz) {
return newRuntimeError(env, "fetchEnum(%s, %s): failed to find class.",
className, valueName);
return getPendingExceptionAndClear(env);
}
if (snprintf(prettyClass, sizeof(prettyClass), "L%s;", className)
>= sizeof(prettyClass)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <pthread.h>
#include <stdio.h>

#include "exception.h"
#include "jni_helper.h"

#define UNKNOWN "UNKNOWN"
#define MAXTHRID 256

Expand All @@ -46,6 +49,7 @@ void hdfsThreadDestructor(void *v)
struct ThreadLocalState *state = (struct ThreadLocalState*)v;
JNIEnv *env = state->env;;
jint ret;
jthrowable jthr;
char thr_name[MAXTHRID];

/* Detach the current thread from the JVM */
Expand All @@ -55,12 +59,20 @@ void hdfsThreadDestructor(void *v)
if (ret != 0) {
fprintf(stderr, "hdfsThreadDestructor: GetJavaVM failed with error %d\n",
ret);
(*env)->ExceptionDescribe(env);
jthr = (*env)->ExceptionOccurred(env);
if (jthr) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
} else {
ret = (*vm)->DetachCurrentThread(vm);

if (ret != JNI_OK) {
(*env)->ExceptionDescribe(env);
jthr = (*env)->ExceptionOccurred(env);
if (jthr) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
get_current_thread_id(env, thr_name, MAXTHRID);

fprintf(stderr, "hdfsThreadDestructor: Unable to detach thread %s "
Expand All @@ -78,44 +90,60 @@ void hdfsThreadDestructor(void *v)
}

static void get_current_thread_id(JNIEnv* env, char* id, int max) {
jclass cls;
jmethodID mth;
jobject thr;
jstring thr_name;
jvalue jVal;
jobject thr = NULL;
jstring thr_name = NULL;
jlong thr_id = 0;
jthrowable jthr = NULL;
const char *thr_name_str;

cls = (*env)->FindClass(env, "java/lang/Thread");
mth = (*env)->GetStaticMethodID(env, cls, "currentThread",
"()Ljava/lang/Thread;");
thr = (*env)->CallStaticObjectMethod(env, cls, mth);

if (thr != NULL) {
mth = (*env)->GetMethodID(env, cls, "getId", "()J");
thr_id = (*env)->CallLongMethod(env, thr, mth);
(*env)->ExceptionDescribe(env);

mth = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;");
thr_name = (jstring)(*env)->CallObjectMethod(env, thr, mth);
jthr = invokeMethod(env, &jVal, STATIC, NULL, "java/lang/Thread",
"currentThread", "()Ljava/lang/Thread;");
if (jthr) {
snprintf(id, max, "%s", UNKNOWN);
printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"get_current_thread_id: Thread#currentThread failed: ");
goto done;
}
thr = jVal.l;

if (thr_name != NULL) {
thr_name_str = (*env)->GetStringUTFChars(env, thr_name, NULL);
jthr = invokeMethod(env, &jVal, INSTANCE, thr, "java/lang/Thread",
"getId", "()J");
if (jthr) {
snprintf(id, max, "%s", UNKNOWN);
printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"get_current_thread_id: Thread#getId failed: ");
goto done;
}
thr_id = jVal.j;

jthr = invokeMethod(env, &jVal, INSTANCE, thr, "java/lang/Thread",
"toString", "()Ljava/lang/String;");
if (jthr) {
snprintf(id, max, "%s:%ld", UNKNOWN, thr_id);
printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"get_current_thread_id: Thread#toString failed: ");
goto done;
}
thr_name = jVal.l;

thr_name_str = (*env)->GetStringUTFChars(env, thr_name, NULL);
if (!thr_name_str) {
printPendingExceptionAndFree(env, PRINT_EXC_ALL,
"get_current_thread_id: GetStringUTFChars failed: ");
snprintf(id, max, "%s:%ld", UNKNOWN, thr_id);
goto done;
}

// Treating the jlong as a long *should* be safe
snprintf(id, max, "%s:%ld", thr_name_str, thr_id);
// Treating the jlong as a long *should* be safe
snprintf(id, max, "%s:%ld", thr_name_str, thr_id);

// Release the char*
(*env)->ReleaseStringUTFChars(env, thr_name, thr_name_str);
} else {
(*env)->ExceptionDescribe(env);
// Release the char*
(*env)->ReleaseStringUTFChars(env, thr_name, thr_name_str);

// Treating the jlong as a long *should* be safe
snprintf(id, max, "%s:%ld", UNKNOWN, thr_id);
}
} else {
(*env)->ExceptionDescribe(env);
snprintf(id, max, "%s", UNKNOWN);
}
done:
destroyLocalReference(env, thr);
destroyLocalReference(env, thr_name);

// Make sure the id is null terminated in case we overflow the max length
id[max - 1] = '\0';
Expand Down