lime
Lime is a C++ library implementing Open Whisper System Signal protocol
advanced_ownership.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <jni/functions.hpp>
4
5namespace jni
6 {
7 // A deleter that gets the JNIEnv via GetEnv, rather than storing the value passed to the constructor.
8 // The deleting thread must have a JVM attachment.
9 //
10 // Useful when deletion will happen on an auxiliary thread, particularly the finalizer thread. In such
11 // cases, you may use one of the following:
12 //
13 // low-level: UniqueGlobalRef<jobject, EnvGettingDeleter> and NewGlobalRef<EnvGettingDeleter>
14 // high-level: Global<Object<Tag>, EnvGettingDeleter> and obj.NewGlobalRef<EnvGettingDeleter>
15 //
16 template < RefDeletionMethod DeleteRef >
18 {
19 private:
20 JavaVM* vm = nullptr;
21
22 public:
23 EnvGettingDeleter() = default;
24 EnvGettingDeleter(JNIEnv& e) : vm(&GetJavaVM(e)) {}
25
26 void operator()(jobject* p) const
27 {
28 if (p)
29 {
30 assert(vm);
31 (GetEnv(*vm).*DeleteRef)(Unwrap(p));
32 }
33 }
34 };
35
36 // A deleter that first tries GetEnv, but falls back to AttachCurrentThread if a JVM is not already attached.
37 // In the latter case, it detaches after deleting the reference.
38 //
39 // Useful when deletion will happen on an auxiliary thread which may or may not have a JVM attachment. In such
40 // cases, you may use one of the following:
41 //
42 // low-level: UniqueGlobalRef<jobject, EnvAttachingDeleter> and NewGlobalRef<EnvAttachingDeleter>
43 // high-level: Global<Object<Tag>, EnvAttachingDeleter> and obj.NewGlobalRef<EnvAttachingDeleter>
44 //
45 template < RefDeletionMethod DeleteRef >
47 {
48 private:
49 JavaVM* vm = nullptr;
50
51 public:
53 EnvAttachingDeleter(JNIEnv& e) : vm(&GetJavaVM(e)) {}
54
55 void operator()(jobject* p) const
56 {
57 if (p)
58 {
59 assert(vm);
60 JNIEnv* env = nullptr;
61 jint err = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_1);
62 if (err == JNI_OK)
63 {
64 (env->*DeleteRef)(Unwrap(p));
65 }
66 else if (err == JNI_EDETACHED)
67 {
68 ((*AttachCurrentThread(*vm)).*DeleteRef)(Unwrap(p));
69 }
70 else
71 {
72 CheckErrorCode(err);
73 }
74 }
75 }
76 };
77
78 // A deleter that tries to get the JNIEnv via GetEnv, and does nothing if that fails.
79 //
80 // This is used to ignore GlobalRef deletions that happen after a thread has been detached,
81 // for instance during process shutdown, when there's no need to release the reference anyway.
82 // Specifically, it's what Class<T>::Singleton uses.
83 //
84 template < RefDeletionMethod DeleteRef >
86 {
87 private:
88 JavaVM* vm = nullptr;
89
90 public:
91 EnvIgnoringDeleter() = default;
92 EnvIgnoringDeleter(JNIEnv& e) : vm(&GetJavaVM(e)) {}
93
94 void operator()(jobject* p) const
95 {
96 if (p)
97 {
98 assert(vm);
99 JNIEnv* env = nullptr;
100 jint err = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_1);
101 if (err == JNI_OK)
102 {
103 (env->*DeleteRef)(Unwrap(p));
104 }
105 else if (err != JNI_EDETACHED)
106 {
107 CheckErrorCode(err);
108 }
109 }
110 }
111 };
112 }
Definition: advanced_ownership.hpp:47
EnvAttachingDeleter(JNIEnv &e)
Definition: advanced_ownership.hpp:53
void operator()(jobject *p) const
Definition: advanced_ownership.hpp:55
Definition: advanced_ownership.hpp:18
void operator()(jobject *p) const
Definition: advanced_ownership.hpp:26
EnvGettingDeleter(JNIEnv &e)
Definition: advanced_ownership.hpp:24
Definition: advanced_ownership.hpp:86
EnvIgnoringDeleter(JNIEnv &e)
Definition: advanced_ownership.hpp:92
void operator()(jobject *p) const
Definition: advanced_ownership.hpp:94
Definition: advanced_ownership.hpp:6
void CheckErrorCode(jint err)
Definition: errors.hpp:43
JavaVM & GetJavaVM(JNIEnv &env)
Definition: functions.hpp:598
UniqueEnv AttachCurrentThread(JavaVM &vm)
Definition: functions.hpp:631
JNIEnv & GetEnv(JavaVM &vm, version version=jni_version_1_1)
Definition: functions.hpp:659
auto Unwrap(W &&w)
Definition: wrapping.hpp:22
Definition: types.hpp:31