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 
5 namespace 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:
52  EnvAttachingDeleter() = default;
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  }
void operator()(jobject *p) const
Definition: advanced_ownership.hpp:55
void operator()(jobject *p) const
Definition: advanced_ownership.hpp:94
UniqueEnv AttachCurrentThread(JavaVM &vm)
Definition: functions.hpp:631
Definition: advanced_ownership.hpp:85
void CheckErrorCode(jint err)
Definition: errors.hpp:43
Definition: advanced_ownership.hpp:5
auto Unwrap(W &&w)
Definition: wrapping.hpp:22
EnvAttachingDeleter(JNIEnv &e)
Definition: advanced_ownership.hpp:53
void operator()(jobject *p) const
Definition: advanced_ownership.hpp:26
EnvIgnoringDeleter(JNIEnv &e)
Definition: advanced_ownership.hpp:92
Definition: advanced_ownership.hpp:17
JNIEnv & GetEnv(JavaVM &vm, version version=jni_version_1_1)
Definition: functions.hpp:659
JavaVM & GetJavaVM(JNIEnv &env)
Definition: functions.hpp:598
Definition: advanced_ownership.hpp:46
Definition: types.hpp:30
EnvGettingDeleter(JNIEnv &e)
Definition: advanced_ownership.hpp:24