JNI generation: Replace base::subtle::AtomicWord with std::atomic<>

This also rolls up //base in DEPS, because it needs to be landed together with
54f759310c

Bug: chromium:867475
Change-Id: I5792cb0610d2df46a9368fd3b1846583aa134b38
Reviewed-on: https://webrtc-review.googlesource.com/90404
Commit-Queue: Oleh Prypin <oprypin@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24180}
This commit is contained in:
Oleh Prypin
2018-08-03 10:05:41 +02:00
committed by Commit Bot
parent e8b4e7e53c
commit 9f6450d5a5
3 changed files with 36 additions and 46 deletions

2
DEPS
View File

@ -42,7 +42,7 @@ deps = {
# TODO(kjellander): Move this to be Android-only once the libevent dependency # TODO(kjellander): Move this to be Android-only once the libevent dependency
# in base/third_party/libevent is solved. # in base/third_party/libevent is solved.
'src/base': 'src/base':
Var('chromium_git') + '/chromium/src/base' + '@' + 'e15177f81ad60f5bf6a00d1244a701e2844796d8', Var('chromium_git') + '/chromium/src/base' + '@' + 'f9ce552913fd38f5b1f21d1e4eed67a815c94791',
'src/build': 'src/build':
Var('chromium_git') + '/chromium/src/build' + '@' + 'fbf92119338eb0d6b4c364cd98a2017b6f7a30c9', Var('chromium_git') + '/chromium/src/build' + '@' + 'fbf92119338eb0d6b4c364cd98a2017b6f7a30c9',
'src/buildtools': 'src/buildtools':

View File

@ -13,28 +13,22 @@
#include "rtc_base/atomicops.h" #include "rtc_base/atomicops.h"
#include "sdk/android/native_api/jni/class_loader.h" #include "sdk/android/native_api/jni/class_loader.h"
namespace base { namespace webrtc {
namespace android {
// If |atomic_class_id| set, it'll return immediately. Otherwise, it will look // If |atomic_class_id| set, it'll return immediately. Otherwise, it will look
// up the class and store it. If there's a race, we take care to only store one // up the class and store it. If there's a race, we take care to only store one
// global reference (and the duplicated effort will happen only once). // global reference (and the duplicated effort will happen only once).
jclass LazyGetClass(JNIEnv* env, jclass LazyGetClass(JNIEnv* env,
const char* class_name, const char* class_name,
base::subtle::AtomicWord* atomic_class_id) { std::atomic<jclass>* atomic_class_id) {
static_assert(sizeof(base::subtle::AtomicWord) >= sizeof(jclass), const jclass value = std::atomic_load(atomic_class_id);
"AtomicWord can't be smaller than jclass");
base::subtle::AtomicWord value =
rtc::AtomicOps::AcquireLoadPtr(atomic_class_id);
if (value) if (value)
return reinterpret_cast<jclass>(value); return value;
webrtc::ScopedJavaGlobalRef<jclass> clazz(webrtc::GetClass(env, class_name)); webrtc::ScopedJavaGlobalRef<jclass> clazz(webrtc::GetClass(env, class_name));
RTC_CHECK(!clazz.is_null()) << class_name; RTC_CHECK(!clazz.is_null()) << class_name;
base::subtle::AtomicWord null_aw = nullptr; jclass cas_result = nullptr;
base::subtle::AtomicWord cas_result = rtc::AtomicOps::CompareAndSwapPtr( if (std::atomic_compare_exchange_strong(atomic_class_id, &cas_result,
atomic_class_id, null_aw, clazz.obj())) {
reinterpret_cast<base::subtle::AtomicWord>(clazz.obj()));
if (cas_result == null_aw) {
// We sucessfully stored |clazz| in |atomic_class_id|, so we are // We sucessfully stored |clazz| in |atomic_class_id|, so we are
// intentionally leaking the global ref since it's now stored there. // intentionally leaking the global ref since it's now stored there.
return clazz.Release(); return clazz.Release();
@ -42,7 +36,7 @@ jclass LazyGetClass(JNIEnv* env,
// Some other thread came before us and stored a global pointer in // Some other thread came before us and stored a global pointer in
// |atomic_class_id|. Relase our global ref and return the ref from the // |atomic_class_id|. Relase our global ref and return the ref from the
// other thread. // other thread.
return reinterpret_cast<jclass>(cas_result); return cas_result;
} }
} }
@ -54,23 +48,18 @@ jmethodID MethodID::LazyGet(JNIEnv* env,
jclass clazz, jclass clazz,
const char* method_name, const char* method_name,
const char* jni_signature, const char* jni_signature,
base::subtle::AtomicWord* atomic_method_id) { std::atomic<jmethodID>* atomic_method_id) {
static_assert(sizeof(base::subtle::AtomicWord) >= sizeof(jmethodID), const jmethodID value = std::atomic_load(atomic_method_id);
"AtomicWord can't be smaller than jMethodID");
base::subtle::AtomicWord value =
rtc::AtomicOps::AcquireLoadPtr(atomic_method_id);
if (value) if (value)
return reinterpret_cast<jmethodID>(value); return value;
jmethodID id = (type == MethodID::TYPE_STATIC) auto get_method_ptr = type == MethodID::TYPE_STATIC
? env->GetStaticMethodID(clazz, method_name, jni_signature) ? &JNIEnv::GetStaticMethodID
: env->GetMethodID(clazz, method_name, jni_signature); : &JNIEnv::GetMethodID;
jmethodID id = (env->*get_method_ptr)(clazz, method_name, jni_signature);
CHECK_EXCEPTION(env) << "error during GetMethodID: " << method_name << ", " CHECK_EXCEPTION(env) << "error during GetMethodID: " << method_name << ", "
<< jni_signature; << jni_signature;
RTC_CHECK(id) << method_name << ", " << jni_signature; RTC_CHECK(id) << method_name << ", " << jni_signature;
std::atomic_store(atomic_method_id, id);
rtc::AtomicOps::CompareAndSwapPtr(
atomic_method_id, base::subtle::AtomicWord(nullptr),
reinterpret_cast<base::subtle::AtomicWord>(id));
return id; return id;
} }
@ -80,14 +69,13 @@ template jmethodID MethodID::LazyGet<MethodID::TYPE_STATIC>(
jclass clazz, jclass clazz,
const char* method_name, const char* method_name,
const char* jni_signature, const char* jni_signature,
base::subtle::AtomicWord* atomic_method_id); std::atomic<jmethodID>* atomic_method_id);
template jmethodID MethodID::LazyGet<MethodID::TYPE_INSTANCE>( template jmethodID MethodID::LazyGet<MethodID::TYPE_INSTANCE>(
JNIEnv* env, JNIEnv* env,
jclass clazz, jclass clazz,
const char* method_name, const char* method_name,
const char* jni_signature, const char* jni_signature,
base::subtle::AtomicWord* atomic_method_id); std::atomic<jmethodID>* atomic_method_id);
} // namespace android } // namespace webrtc
} // namespace base

View File

@ -15,6 +15,7 @@
#define SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_ #define SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
#include <jni.h> #include <jni.h>
#include <atomic>
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "sdk/android/native_api/jni/jni_int_wrapper.h" #include "sdk/android/native_api/jni/jni_int_wrapper.h"
@ -38,18 +39,7 @@ inline void CheckException(JNIEnv* env) {
} }
} // namespace jni_generator } // namespace jni_generator
namespace base { namespace webrtc {
namespace subtle {
// This needs to be a type that is big enough to store a jobject/jclass.
typedef void* AtomicWord;
} // namespace subtle
namespace android {
using webrtc::JavaRef;
using webrtc::ScopedJavaLocalRef;
using webrtc::JavaParamRef;
// This function will initialize |atomic_class_id| to contain a global ref to // This function will initialize |atomic_class_id| to contain a global ref to
// the given class, and will return that ref on subsequent calls. The caller is // the given class, and will return that ref on subsequent calls. The caller is
@ -58,7 +48,7 @@ using webrtc::JavaParamRef;
// |atomic_method_id|. // |atomic_method_id|.
jclass LazyGetClass(JNIEnv* env, jclass LazyGetClass(JNIEnv* env,
const char* class_name, const char* class_name,
base::subtle::AtomicWord* atomic_class_id); std::atomic<jclass>* atomic_class_id);
// This class is a wrapper for JNIEnv Get(Static)MethodID. // This class is a wrapper for JNIEnv Get(Static)MethodID.
class MethodID { class MethodID {
@ -78,9 +68,21 @@ class MethodID {
jclass clazz, jclass clazz,
const char* method_name, const char* method_name,
const char* jni_signature, const char* jni_signature,
base::subtle::AtomicWord* atomic_method_id); std::atomic<jmethodID>* atomic_method_id);
}; };
} // namespace webrtc
// Re-export relevant classes into the namespaces the script expects.
namespace base {
namespace android {
using webrtc::JavaParamRef;
using webrtc::JavaRef;
using webrtc::ScopedJavaLocalRef;
using webrtc::LazyGetClass;
using webrtc::MethodID;
} // namespace android } // namespace android
} // namespace base } // namespace base