Add the condition variable to System.loadLibrary and implement UnregisterNatives.
Also change PrettyDescriptor now descriptors are String*s rather than StringPiece&s.
Change-Id: Id07affb26038f5f4a3bee4396c65f71d7bc38be3
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 79986c2..c5b06bb 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -57,6 +57,7 @@
jni_on_load_lock_(Mutex::Create("JNI_OnLoad lock")),
jni_on_load_tid_(Thread::Current()->GetId()),
jni_on_load_result_(kPending) {
+ pthread_cond_init(&jni_on_load_cond_, NULL);
}
~SharedLibrary() {
@@ -81,8 +82,7 @@
return true;
}
- UNIMPLEMENTED(ERROR) << "need to pthread_cond_wait!";
- // MutexLock mu(jni_on_load_lock_);
+ MutexLock mu(jni_on_load_lock_);
while (jni_on_load_result_ == kPending) {
if (vm->verbose_jni) {
LOG(INFO) << "[" << *self << " waiting for \"" << path_ << "\" "
@@ -90,7 +90,7 @@
}
Thread::State old_state = self->GetState();
self->SetState(Thread::kWaiting); // TODO: VMWAIT
- // pthread_cond_wait(&jni_on_load_cond_, &jni_on_load_lock_);
+ pthread_cond_wait(&jni_on_load_cond_, &(jni_on_load_lock_->lock_impl_));
self->SetState(old_state);
}
@@ -107,9 +107,8 @@
jni_on_load_tid_ = 0;
// Broadcast a wakeup to anybody sleeping on the condition variable.
- UNIMPLEMENTED(ERROR) << "missing pthread_cond_broadcast";
- // MutexLock mu(library->jni_on_load_lock_);
- // pthread_cond_broadcast(&library->jni_on_load_cond_);
+ MutexLock mu(jni_on_load_lock_);
+ pthread_cond_broadcast(&jni_on_load_cond_);
}
private:
@@ -2021,11 +2020,13 @@
SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(ts, array, start, length, buf);
}
- static jint RegisterNatives(JNIEnv* env,
- jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+ static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, jint method_count) {
ScopedJniThreadState ts(env);
- Class* klass = Decode<Class*>(ts, clazz);
- for(int i = 0; i < nMethods; i++) {
+ Class* c = Decode<Class*>(ts, java_class);
+
+ JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+
+ for (int i = 0; i < method_count; i++) {
const char* name = methods[i].name;
const char* sig = methods[i].signature;
@@ -2034,34 +2035,60 @@
++sig;
}
- Method* method = klass->FindDirectMethod(name, sig);
- if (method == NULL) {
- method = klass->FindVirtualMethod(name, sig);
+ Method* m = c->FindDirectMethod(name, sig);
+ if (m == NULL) {
+ m = c->FindVirtualMethod(name, sig);
}
- if (method == NULL) {
+ if (m == NULL) {
Thread* self = Thread::Current();
- std::string class_descriptor(klass->GetDescriptor()->ToModifiedUtf8());
+ std::string class_descriptor(c->GetDescriptor()->ToModifiedUtf8());
self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
"no method \"%s.%s%s\"",
class_descriptor.c_str(), name, sig);
return JNI_ERR;
- } else if (!method->IsNative()) {
+ } else if (!m->IsNative()) {
Thread* self = Thread::Current();
- std::string class_descriptor(klass->GetDescriptor()->ToModifiedUtf8());
+ std::string class_descriptor(c->GetDescriptor()->ToModifiedUtf8());
self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
"method \"%s.%s%s\" is not native",
class_descriptor.c_str(), name, sig);
return JNI_ERR;
}
- method->RegisterNative(methods[i].fnPtr);
+
+ if (vm->verbose_jni) {
+ LOG(INFO) << "[Registering JNI native method "
+ << PrettyMethod(m, true) << "]";
+ }
+
+ m->RegisterNative(methods[i].fnPtr);
}
return JNI_OK;
}
- static jint UnregisterNatives(JNIEnv* env, jclass clazz) {
+ static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ Class* c = Decode<Class*>(ts, java_class);
+
+ JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+ if (vm->verbose_jni) {
+ LOG(INFO) << "[Unregistering JNI native methods for "
+ << PrettyDescriptor(c->GetDescriptor()) << "]";
+ }
+
+ for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
+ Method* m = c->GetDirectMethod(i);
+ if (m->IsNative()) {
+ m->UnregisterNative();
+ }
+ }
+ for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
+ Method* m = c->GetVirtualMethod(i);
+ if (m->IsNative()) {
+ m->UnregisterNative();
+ }
+ }
+
+ return JNI_OK;
}
static jint MonitorEnter(JNIEnv* env, jobject obj) {
@@ -2630,8 +2657,6 @@
// Create a new entry.
library = new SharedLibrary(path, handle, class_loader);
- UNIMPLEMENTED(ERROR) << "missing pthread_cond_init";
- // pthread_cond_init(&library->onLoadCond, NULL);
libraries[path] = library;