1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 // This file implements the callback "bridge" between Java and C++ for
7 // JNI Callbacks from C++ to sub-classes or org.rocksdb.RocksCallbackObject
8 
9 #include <assert.h>
10 #include "rocksjni/jnicallback.h"
11 #include "rocksjni/portal.h"
12 
13 namespace ROCKSDB_NAMESPACE {
JniCallback(JNIEnv * env,jobject jcallback_obj)14 JniCallback::JniCallback(JNIEnv* env, jobject jcallback_obj) {
15   // Note: jcallback_obj may be accessed by multiple threads,
16   // so we ref the jvm not the env
17   const jint rs = env->GetJavaVM(&m_jvm);
18   if(rs != JNI_OK) {
19     // exception thrown
20     return;
21   }
22 
23   // Note: we may want to access the Java callback object instance
24   // across multiple method calls, so we create a global ref
25   assert(jcallback_obj != nullptr);
26   m_jcallback_obj = env->NewGlobalRef(jcallback_obj);
27   if(jcallback_obj == nullptr) {
28     // exception thrown: OutOfMemoryError
29     return;
30   }
31 }
32 
getJniEnv(jboolean * attached) const33 JNIEnv* JniCallback::getJniEnv(jboolean* attached) const {
34   return JniUtil::getJniEnv(m_jvm, attached);
35 }
36 
releaseJniEnv(jboolean & attached) const37 void JniCallback::releaseJniEnv(jboolean& attached) const {
38   JniUtil::releaseJniEnv(m_jvm, attached);
39 }
40 
~JniCallback()41 JniCallback::~JniCallback() {
42   jboolean attached_thread = JNI_FALSE;
43   JNIEnv* env = getJniEnv(&attached_thread);
44   assert(env != nullptr);
45 
46   if(m_jcallback_obj != nullptr) {
47     env->DeleteGlobalRef(m_jcallback_obj);
48   }
49 
50   releaseJniEnv(attached_thread);
51 }
52 // @lint-ignore TXT4 T25377293 Grandfathered in
53 }  // namespace ROCKSDB_NAMESPACE