fork of https://github.com/rust-rocksdb/rust-rocksdb for nextgraph
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
503 lines
17 KiB
503 lines
17 KiB
1 year ago
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||
|
// This source code is licensed under both the GPLv2 (found in the
|
||
|
// COPYING file in the root directory) and Apache 2.0 License
|
||
|
// (found in the LICENSE.Apache file in the root directory).
|
||
|
//
|
||
|
// This file implements the callback "bridge" between Java and C++ for
|
||
|
// ROCKSDB_NAMESPACE::EventListener.
|
||
|
|
||
|
#include "rocksjni/event_listener_jnicallback.h"
|
||
|
|
||
|
#include "rocksjni/portal.h"
|
||
|
|
||
|
namespace ROCKSDB_NAMESPACE {
|
||
|
EventListenerJniCallback::EventListenerJniCallback(
|
||
|
JNIEnv* env, jobject jevent_listener,
|
||
|
const std::set<EnabledEventCallback>& enabled_event_callbacks)
|
||
|
: JniCallback(env, jevent_listener),
|
||
|
m_enabled_event_callbacks(enabled_event_callbacks) {
|
||
|
InitCallbackMethodId(
|
||
|
m_on_flush_completed_proxy_mid, EnabledEventCallback::ON_FLUSH_COMPLETED,
|
||
|
env, AbstractEventListenerJni::getOnFlushCompletedProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_flush_begin_proxy_mid,
|
||
|
EnabledEventCallback::ON_FLUSH_BEGIN, env,
|
||
|
AbstractEventListenerJni::getOnFlushBeginProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_table_file_deleted_mid,
|
||
|
EnabledEventCallback::ON_TABLE_FILE_DELETED, env,
|
||
|
AbstractEventListenerJni::getOnTableFileDeletedMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_compaction_begin_proxy_mid,
|
||
|
EnabledEventCallback::ON_COMPACTION_BEGIN, env,
|
||
|
AbstractEventListenerJni::getOnCompactionBeginProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_compaction_completed_proxy_mid,
|
||
|
EnabledEventCallback::ON_COMPACTION_COMPLETED, env,
|
||
|
AbstractEventListenerJni::getOnCompactionCompletedProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_table_file_created_mid,
|
||
|
EnabledEventCallback::ON_TABLE_FILE_CREATED, env,
|
||
|
AbstractEventListenerJni::getOnTableFileCreatedMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_table_file_creation_started_mid,
|
||
|
EnabledEventCallback::ON_TABLE_FILE_CREATION_STARTED, env,
|
||
|
AbstractEventListenerJni::getOnTableFileCreationStartedMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_mem_table_sealed_mid,
|
||
|
EnabledEventCallback::ON_MEMTABLE_SEALED, env,
|
||
|
AbstractEventListenerJni::getOnMemTableSealedMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_column_family_handle_deletion_started_mid,
|
||
|
EnabledEventCallback::ON_COLUMN_FAMILY_HANDLE_DELETION_STARTED, env,
|
||
|
AbstractEventListenerJni::getOnColumnFamilyHandleDeletionStartedMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_external_file_ingested_proxy_mid,
|
||
|
EnabledEventCallback::ON_EXTERNAL_FILE_INGESTED, env,
|
||
|
AbstractEventListenerJni::getOnExternalFileIngestedProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_background_error_proxy_mid,
|
||
|
EnabledEventCallback::ON_BACKGROUND_ERROR, env,
|
||
|
AbstractEventListenerJni::getOnBackgroundErrorProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_stall_conditions_changed_mid,
|
||
|
EnabledEventCallback::ON_STALL_CONDITIONS_CHANGED, env,
|
||
|
AbstractEventListenerJni::getOnStallConditionsChangedMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_file_read_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_READ_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileReadFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_file_write_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_WRITE_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileWriteFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_file_flush_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_FLUSH_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileFlushFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_file_sync_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_SYNC_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileSyncFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_file_range_sync_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_RANGE_SYNC_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileRangeSyncFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_file_truncate_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_TRUNCATE_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileTruncateFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(m_on_file_close_finish_mid,
|
||
|
EnabledEventCallback::ON_FILE_CLOSE_FINISH, env,
|
||
|
AbstractEventListenerJni::getOnFileCloseFinishMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_should_be_notified_on_file_io,
|
||
|
EnabledEventCallback::SHOULD_BE_NOTIFIED_ON_FILE_IO, env,
|
||
|
AbstractEventListenerJni::getShouldBeNotifiedOnFileIOMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_error_recovery_begin_proxy_mid,
|
||
|
EnabledEventCallback::ON_ERROR_RECOVERY_BEGIN, env,
|
||
|
AbstractEventListenerJni::getOnErrorRecoveryBeginProxyMethodId);
|
||
|
|
||
|
InitCallbackMethodId(
|
||
|
m_on_error_recovery_completed_mid,
|
||
|
EnabledEventCallback::ON_ERROR_RECOVERY_COMPLETED, env,
|
||
|
AbstractEventListenerJni::getOnErrorRecoveryCompletedMethodId);
|
||
|
}
|
||
|
|
||
|
EventListenerJniCallback::~EventListenerJniCallback() {}
|
||
|
|
||
|
void EventListenerJniCallback::OnFlushCompleted(
|
||
|
DB* db, const FlushJobInfo& flush_job_info) {
|
||
|
if (m_on_flush_completed_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jflush_job_info = SetupCallbackInvocation<FlushJobInfo>(
|
||
|
env, attached_thread, flush_job_info,
|
||
|
FlushJobInfoJni::fromCppFlushJobInfo);
|
||
|
|
||
|
if (jflush_job_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_flush_completed_proxy_mid,
|
||
|
reinterpret_cast<jlong>(db), jflush_job_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jflush_job_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFlushBegin(
|
||
|
DB* db, const FlushJobInfo& flush_job_info) {
|
||
|
if (m_on_flush_begin_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jflush_job_info = SetupCallbackInvocation<FlushJobInfo>(
|
||
|
env, attached_thread, flush_job_info,
|
||
|
FlushJobInfoJni::fromCppFlushJobInfo);
|
||
|
|
||
|
if (jflush_job_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_flush_begin_proxy_mid,
|
||
|
reinterpret_cast<jlong>(db), jflush_job_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jflush_job_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnTableFileDeleted(
|
||
|
const TableFileDeletionInfo& info) {
|
||
|
if (m_on_table_file_deleted_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jdeletion_info = SetupCallbackInvocation<TableFileDeletionInfo>(
|
||
|
env, attached_thread, info,
|
||
|
TableFileDeletionInfoJni::fromCppTableFileDeletionInfo);
|
||
|
|
||
|
if (jdeletion_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_table_file_deleted_mid,
|
||
|
jdeletion_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jdeletion_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnCompactionBegin(DB* db,
|
||
|
const CompactionJobInfo& ci) {
|
||
|
if (m_on_compaction_begin_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jcompaction_job_info = SetupCallbackInvocation<CompactionJobInfo>(
|
||
|
env, attached_thread, ci, CompactionJobInfoJni::fromCppCompactionJobInfo);
|
||
|
|
||
|
if (jcompaction_job_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_compaction_begin_proxy_mid,
|
||
|
reinterpret_cast<jlong>(db), jcompaction_job_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jcompaction_job_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnCompactionCompleted(
|
||
|
DB* db, const CompactionJobInfo& ci) {
|
||
|
if (m_on_compaction_completed_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jcompaction_job_info = SetupCallbackInvocation<CompactionJobInfo>(
|
||
|
env, attached_thread, ci, CompactionJobInfoJni::fromCppCompactionJobInfo);
|
||
|
|
||
|
if (jcompaction_job_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_compaction_completed_proxy_mid,
|
||
|
reinterpret_cast<jlong>(db), jcompaction_job_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jcompaction_job_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnTableFileCreated(
|
||
|
const TableFileCreationInfo& info) {
|
||
|
if (m_on_table_file_created_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jfile_creation_info = SetupCallbackInvocation<TableFileCreationInfo>(
|
||
|
env, attached_thread, info,
|
||
|
TableFileCreationInfoJni::fromCppTableFileCreationInfo);
|
||
|
|
||
|
if (jfile_creation_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_table_file_created_mid,
|
||
|
jfile_creation_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jfile_creation_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnTableFileCreationStarted(
|
||
|
const TableFileCreationBriefInfo& info) {
|
||
|
if (m_on_table_file_creation_started_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jcreation_brief_info =
|
||
|
SetupCallbackInvocation<TableFileCreationBriefInfo>(
|
||
|
env, attached_thread, info,
|
||
|
TableFileCreationBriefInfoJni::fromCppTableFileCreationBriefInfo);
|
||
|
|
||
|
if (jcreation_brief_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_table_file_creation_started_mid,
|
||
|
jcreation_brief_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jcreation_brief_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnMemTableSealed(const MemTableInfo& info) {
|
||
|
if (m_on_mem_table_sealed_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jmem_table_info = SetupCallbackInvocation<MemTableInfo>(
|
||
|
env, attached_thread, info, MemTableInfoJni::fromCppMemTableInfo);
|
||
|
|
||
|
if (jmem_table_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_mem_table_sealed_mid,
|
||
|
jmem_table_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jmem_table_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnColumnFamilyHandleDeletionStarted(
|
||
|
ColumnFamilyHandle* handle) {
|
||
|
if (m_on_column_family_handle_deletion_started_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jcf_handle = SetupCallbackInvocation<ColumnFamilyHandle>(
|
||
|
env, attached_thread, *handle,
|
||
|
ColumnFamilyHandleJni::fromCppColumnFamilyHandle);
|
||
|
|
||
|
if (jcf_handle != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj,
|
||
|
m_on_column_family_handle_deletion_started_mid,
|
||
|
jcf_handle);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jcf_handle});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnExternalFileIngested(
|
||
|
DB* db, const ExternalFileIngestionInfo& info) {
|
||
|
if (m_on_external_file_ingested_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jingestion_info = SetupCallbackInvocation<ExternalFileIngestionInfo>(
|
||
|
env, attached_thread, info,
|
||
|
ExternalFileIngestionInfoJni::fromCppExternalFileIngestionInfo);
|
||
|
|
||
|
if (jingestion_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_external_file_ingested_proxy_mid,
|
||
|
reinterpret_cast<jlong>(db), jingestion_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jingestion_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnBackgroundError(BackgroundErrorReason reason,
|
||
|
Status* bg_error) {
|
||
|
if (m_on_background_error_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jstatus = SetupCallbackInvocation<Status>(
|
||
|
env, attached_thread, *bg_error, StatusJni::construct);
|
||
|
|
||
|
if (jstatus != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_background_error_proxy_mid,
|
||
|
static_cast<jbyte>(reason), jstatus);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jstatus});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnStallConditionsChanged(
|
||
|
const WriteStallInfo& info) {
|
||
|
if (m_on_stall_conditions_changed_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jwrite_stall_info = SetupCallbackInvocation<WriteStallInfo>(
|
||
|
env, attached_thread, info, WriteStallInfoJni::fromCppWriteStallInfo);
|
||
|
|
||
|
if (jwrite_stall_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_stall_conditions_changed_mid,
|
||
|
jwrite_stall_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jwrite_stall_info});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileReadFinish(const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_read_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileWriteFinish(
|
||
|
const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_write_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileFlushFinish(
|
||
|
const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_flush_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileSyncFinish(const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_sync_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileRangeSyncFinish(
|
||
|
const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_range_sync_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileTruncateFinish(
|
||
|
const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_truncate_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileCloseFinish(
|
||
|
const FileOperationInfo& info) {
|
||
|
OnFileOperation(m_on_file_close_finish_mid, info);
|
||
|
}
|
||
|
|
||
|
bool EventListenerJniCallback::ShouldBeNotifiedOnFileIO() {
|
||
|
if (m_should_be_notified_on_file_io == nullptr) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
jboolean attached_thread = JNI_FALSE;
|
||
|
JNIEnv* env = getJniEnv(&attached_thread);
|
||
|
assert(env != nullptr);
|
||
|
|
||
|
jboolean jshould_be_notified =
|
||
|
env->CallBooleanMethod(m_jcallback_obj, m_should_be_notified_on_file_io);
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {});
|
||
|
|
||
|
return static_cast<bool>(jshould_be_notified);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnErrorRecoveryBegin(
|
||
|
BackgroundErrorReason reason, Status bg_error, bool* auto_recovery) {
|
||
|
if (m_on_error_recovery_begin_proxy_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jbg_error = SetupCallbackInvocation<Status>(
|
||
|
env, attached_thread, bg_error, StatusJni::construct);
|
||
|
|
||
|
if (jbg_error != nullptr) {
|
||
|
jboolean jauto_recovery = env->CallBooleanMethod(
|
||
|
m_jcallback_obj, m_on_error_recovery_begin_proxy_mid,
|
||
|
static_cast<jbyte>(reason), jbg_error);
|
||
|
*auto_recovery = jauto_recovery == JNI_TRUE;
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jbg_error});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnErrorRecoveryCompleted(Status old_bg_error) {
|
||
|
if (m_on_error_recovery_completed_mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jold_bg_error = SetupCallbackInvocation<Status>(
|
||
|
env, attached_thread, old_bg_error, StatusJni::construct);
|
||
|
|
||
|
if (jold_bg_error != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, m_on_error_recovery_completed_mid,
|
||
|
jold_bg_error);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jold_bg_error});
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::InitCallbackMethodId(
|
||
|
jmethodID& mid, EnabledEventCallback eec, JNIEnv* env,
|
||
|
jmethodID (*get_id)(JNIEnv* env)) {
|
||
|
if (m_enabled_event_callbacks.count(eec) == 1) {
|
||
|
mid = get_id(env);
|
||
|
} else {
|
||
|
mid = nullptr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
jobject EventListenerJniCallback::SetupCallbackInvocation(
|
||
|
JNIEnv*& env, jboolean& attached_thread, const T& cpp_obj,
|
||
|
jobject (*convert)(JNIEnv* env, const T* cpp_obj)) {
|
||
|
attached_thread = JNI_FALSE;
|
||
|
env = getJniEnv(&attached_thread);
|
||
|
assert(env != nullptr);
|
||
|
|
||
|
return convert(env, &cpp_obj);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::CleanupCallbackInvocation(
|
||
|
JNIEnv* env, jboolean attached_thread,
|
||
|
std::initializer_list<jobject*> refs) {
|
||
|
for (auto* ref : refs) {
|
||
|
if (*ref == nullptr) continue;
|
||
|
env->DeleteLocalRef(*ref);
|
||
|
}
|
||
|
|
||
|
if (env->ExceptionCheck()) {
|
||
|
// exception thrown from CallVoidMethod
|
||
|
env->ExceptionDescribe(); // print out exception to stderr
|
||
|
}
|
||
|
|
||
|
releaseJniEnv(attached_thread);
|
||
|
}
|
||
|
|
||
|
void EventListenerJniCallback::OnFileOperation(const jmethodID& mid,
|
||
|
const FileOperationInfo& info) {
|
||
|
if (mid == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
JNIEnv* env;
|
||
|
jboolean attached_thread;
|
||
|
jobject jop_info = SetupCallbackInvocation<FileOperationInfo>(
|
||
|
env, attached_thread, info,
|
||
|
FileOperationInfoJni::fromCppFileOperationInfo);
|
||
|
|
||
|
if (jop_info != nullptr) {
|
||
|
env->CallVoidMethod(m_jcallback_obj, mid, jop_info);
|
||
|
}
|
||
|
|
||
|
CleanupCallbackInvocation(env, attached_thread, {&jop_info});
|
||
|
}
|
||
|
} // namespace ROCKSDB_NAMESPACE
|