Use static thread safety analysis when available, and fix the bugs GCC finds.

It's impossible to express the Heap locking and the ThreadList locking with
GCC, but Clang is supposed to be able to do it. This patch does what's possible
for now.

Change-Id: Ib64a890c9d27c6ce255d5003cb755c2ef1beba95
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 4f01f7d..82fba54 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -621,6 +621,8 @@
    * If the call has not yet finished in another thread, wait for it.
    */
   bool CheckOnLoadResult() {
+    MutexLock mu(jni_on_load_lock_);
+
     Thread* self = Thread::Current();
     if (jni_on_load_thread_id_ == self->GetThinLockId()) {
       // Check this so we don't end up waiting for ourselves.  We need
@@ -630,7 +632,6 @@
       return true;
     }
 
-    MutexLock mu(jni_on_load_lock_);
     while (jni_on_load_result_ == kPending) {
       VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" "
                 << "JNI_OnLoad...]";
@@ -645,11 +646,12 @@
   }
 
   void SetResult(bool result) {
+    MutexLock mu(jni_on_load_lock_);
+
     jni_on_load_result_ = result ? kOkay : kFailed;
     jni_on_load_thread_id_ = 0;
 
     // Broadcast a wakeup to anybody sleeping on the condition variable.
-    MutexLock mu(jni_on_load_lock_);
     jni_on_load_cond_.Broadcast();
   }
 
@@ -678,9 +680,9 @@
   // Wait for JNI_OnLoad in other thread.
   ConditionVariable jni_on_load_cond_;
   // Recursive invocation guard.
-  uint32_t jni_on_load_thread_id_;
+  uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
   // Result of earlier JNI_OnLoad call.
-  JNI_OnLoadState jni_on_load_result_;
+  JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
 };
 
 // This exists mainly to keep implementation details out of the header file.