Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: base/android/jni_android.cc

Issue 8769005: Don't use Singleton to cache JNI method IDs in Java Bridge (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rename test file, fix comments Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/android/jni_android.h ('k') | base/android/jni_android_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/android/jni_android.h" 5 #include "base/android/jni_android.h"
6 6
7 #include <map>
8
7 #include "base/android/scoped_java_ref.h" 9 #include "base/android/scoped_java_ref.h"
10 #include "base/atomicops.h"
11 #include "base/lazy_instance.h"
8 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/threading/platform_thread.h"
9 14
10 namespace { 15 namespace {
11 JavaVM* g_jvm = 0; 16 JavaVM* g_jvm = 0;
12 jobject g_application_context = NULL; 17 jobject g_application_context = NULL;
18
19 struct MethodIdentifier {
20 const char* class_name;
21 const char* method;
22 const char* jni_signature;
23
24 bool operator<(const MethodIdentifier& other) const {
25 int r = strcmp(class_name, other.class_name);
26 if (r < 0) {
27 return true;
28 } else if (r > 0) {
29 return false;
30 }
31
32 r = strcmp(method, other.method);
33 if (r < 0) {
34 return true;
35 } else if (r > 0) {
36 return false;
37 }
38
39 return strcmp(jni_signature, other.jni_signature) < 0;
40 }
41 };
42
43 typedef std::map<MethodIdentifier, jmethodID> MethodIDMap;
44 base::LazyInstance<MethodIDMap, base::LeakyLazyInstanceTraits<MethodIDMap> >
45 g_method_id_map = LAZY_INSTANCE_INITIALIZER;
46 const base::subtle::AtomicWord kUnlocked = 0;
47 const base::subtle::AtomicWord kLocked = 1;
48 base::subtle::AtomicWord g_method_id_map_lock = kUnlocked;
49
13 } 50 }
14 51
15 namespace base { 52 namespace base {
16 namespace android { 53 namespace android {
17 54
18 JNIEnv* AttachCurrentThread() { 55 JNIEnv* AttachCurrentThread() {
19 if (!g_jvm) 56 if (!g_jvm)
20 return NULL; 57 return NULL;
21 58
22 JNIEnv* env = NULL; 59 JNIEnv* env = NULL;
(...skipping 17 matching lines...) Expand all
40 void InitApplicationContext(jobject context) { 77 void InitApplicationContext(jobject context) {
41 DCHECK(!g_application_context); 78 DCHECK(!g_application_context);
42 g_application_context = context; 79 g_application_context = context;
43 } 80 }
44 81
45 jobject GetApplicationContext() { 82 jobject GetApplicationContext() {
46 DCHECK(g_application_context); 83 DCHECK(g_application_context);
47 return g_application_context; 84 return g_application_context;
48 } 85 }
49 86
50 MethodID::MethodID(JNIEnv* env, const char* class_name, const char* method, 87 jmethodID GetMethodIDFromClassName(JNIEnv* env,
51 const char* jni_signature) { 88 const char* class_name,
89 const char* method,
90 const char* jni_signature) {
91 MethodIdentifier key;
92 key.class_name = class_name;
93 key.method = method;
94 key.jni_signature = jni_signature;
95
96 MethodIDMap* map = g_method_id_map.Pointer();
97 bool found = false;
98
99 while (base::subtle::Acquire_CompareAndSwap(&g_method_id_map_lock,
100 kUnlocked,
101 kLocked) != kUnlocked) {
102 base::PlatformThread::YieldCurrentThread();
103 }
104 MethodIDMap::const_iterator iter = map->find(key);
105 if (iter != map->end()) {
106 found = true;
107 }
108 base::subtle::Release_Store(&g_method_id_map_lock, kUnlocked);
109
110 // Addition to the map does not invalidate this iterator.
111 if (found) {
112 return iter->second;
113 }
114
52 ScopedJavaLocalRef<jclass> clazz(env, env->FindClass(class_name)); 115 ScopedJavaLocalRef<jclass> clazz(env, env->FindClass(class_name));
53 id_ = GetMethodID(env, clazz.obj(), method, jni_signature); 116 jmethodID id = GetMethodID(env, clazz.obj(), method, jni_signature);
117
118 while (base::subtle::Acquire_CompareAndSwap(&g_method_id_map_lock,
119 kUnlocked,
120 kLocked) != kUnlocked) {
121 base::PlatformThread::YieldCurrentThread();
122 }
123 // Another thread may have populated the map already.
124 std::pair<MethodIDMap::const_iterator, bool> result =
125 map->insert(std::make_pair(key, id));
126 DCHECK_EQ(id, result.first->second);
127 base::subtle::Release_Store(&g_method_id_map_lock, kUnlocked);
128
129 return id;
54 } 130 }
55 131
56 jmethodID GetMethodID(JNIEnv* env, 132 jmethodID GetMethodID(JNIEnv* env,
57 jclass clazz, 133 jclass clazz,
58 const char* const method, 134 const char* const method,
59 const char* const jni_signature) { 135 const char* const jni_signature) {
60 jmethodID id = env->GetMethodID(clazz, method, jni_signature); 136 jmethodID id = env->GetMethodID(clazz, method, jni_signature);
61 DCHECK(id) << method; 137 DCHECK(id) << method;
62 CheckException(env); 138 CheckException(env);
63 return id; 139 return id;
(...skipping 22 matching lines...) Expand all
86 bool CheckException(JNIEnv* env) { 162 bool CheckException(JNIEnv* env) {
87 if (env->ExceptionCheck() == JNI_FALSE) 163 if (env->ExceptionCheck() == JNI_FALSE)
88 return false; 164 return false;
89 env->ExceptionDescribe(); 165 env->ExceptionDescribe();
90 env->ExceptionClear(); 166 env->ExceptionClear();
91 return true; 167 return true;
92 } 168 }
93 169
94 } // namespace android 170 } // namespace android
95 } // namespace base 171 } // namespace base
OLDNEW
« no previous file with comments | « base/android/jni_android.h ('k') | base/android/jni_android_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698