blob: f439c45d8cf71b2fb76ef3ba8f967adb94335122 [file] [log] [blame]
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +02001/*
Tony Mak6c4cc672018-09-17 11:48:50 +01002 * Copyright (C) 2018 The Android Open Source Project
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +02003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Tony Mak6c4cc672018-09-17 11:48:50 +010017#ifndef LIBTEXTCLASSIFIER_UTILS_JAVA_SCOPED_LOCAL_REF_H_
18#define LIBTEXTCLASSIFIER_UTILS_JAVA_SCOPED_LOCAL_REF_H_
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020019
20#include <jni.h>
21#include <memory>
22#include <type_traits>
23
Tony Mak6c4cc672018-09-17 11:48:50 +010024#include "utils/base/logging.h"
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020025
Tony Mak6c4cc672018-09-17 11:48:50 +010026namespace libtextclassifier3 {
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020027
28// A deleter to be used with std::unique_ptr to delete JNI local references.
29class LocalRefDeleter {
30 public:
Lukas Zilkab23e2122018-02-09 10:25:19 +010031 LocalRefDeleter() : env_(nullptr) {}
32
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020033 // Style guide violating implicit constructor so that the LocalRefDeleter
34 // is implicitly constructed from the second argument to ScopedLocalRef.
35 LocalRefDeleter(JNIEnv* env) : env_(env) {} // NOLINT(runtime/explicit)
36
37 LocalRefDeleter(const LocalRefDeleter& orig) = default;
38
39 // Copy assignment to allow move semantics in ScopedLocalRef.
40 LocalRefDeleter& operator=(const LocalRefDeleter& rhs) {
41 // As the deleter and its state are thread-local, ensure the envs
42 // are consistent but do nothing.
Tony Mak6c4cc672018-09-17 11:48:50 +010043 TC3_CHECK_EQ(env_, rhs.env_);
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020044 return *this;
45 }
46
47 // The delete operator.
Lukas Zilkab23e2122018-02-09 10:25:19 +010048 void operator()(jobject object) const {
49 if (env_) {
50 env_->DeleteLocalRef(object);
51 }
52 }
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020053
54 private:
55 // The env_ stashed to use for deletion. Thread-local, don't share!
56 JNIEnv* const env_;
57};
58
59// A smart pointer that deletes a JNI local reference when it goes out
60// of scope. Usage is:
61// ScopedLocalRef<jobject> scoped_local(env->JniFunction(), env);
62//
63// Note that this class is not thread-safe since it caches JNIEnv in
64// the deleter. Do not use the same jobject across different threads.
65template <typename T>
66using ScopedLocalRef =
67 std::unique_ptr<typename std::remove_pointer<T>::type, LocalRefDeleter>;
68
Tony Mak6c4cc672018-09-17 11:48:50 +010069} // namespace libtextclassifier3
Lukas Zilkae5ea2ab2017-10-11 10:50:05 +020070
Tony Mak6c4cc672018-09-17 11:48:50 +010071#endif // LIBTEXTCLASSIFIER_UTILS_JAVA_SCOPED_LOCAL_REF_H_