jaulib v1.3.0
Jau Support Library (C++, Java, ..)
jni_mem.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 * Copyright (c) 2020 ZAFENA AB
5 *
6 * Author: Petre Eftime <petre.p.eftime@intel.com>
7 * Copyright (c) 2016 Intel Corporation.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29#ifndef JAU_JNIMEM__HPP_
30#define JAU_JNIMEM__HPP_
31
32#include <jni.h>
33#include <stdexcept>
34#include <mutex>
35
36#include <jau/basic_types.hpp>
37
38namespace jau::jni {
39
40/** \addtogroup JavaVM
41 *
42 * @{
43 */
44
45extern JavaVM* vm;
46
47
48/*
49 * This class provides a lifetime-managed JNIEnv object, which attaches or
50 * detaches the current thread from the JVM automatically
51 */
53private:
54 JNIEnv *env = nullptr;
55 bool needsDetach = false;
56
57public:
58 /* Attaches this thread to the JVM if it is not already attached */
60 /* Detaches this thread to the JVM if it is attached */
62
63 /* Provides access to the local thread's JNIEnv object */
64 JNIEnv *operator*();
65 /* Provides access to the local thread's JNIEnv object's methods */
66 JNIEnv *operator->();
67
68 /* Attaches this thread to the JVM if it is not already attached */
69 void attach();
70 /* Detaches this thread to the JVM if it is attached */
71 void detach();
72};
73
74/* Each thread has a local jni_env variable of JNIEnvContainer type */
75extern thread_local JNIEnvContainer jni_env;
76
77class JavaGlobalObj; // fwd
78
79/*
80 * This class provides a lifetime-managed GlobalRef variable,
81 * which is automatically deleted when it goes out of scope.
82 *
83 * RAII-style acquire and relinquish via destructor
84 */
86private:
87 friend class JavaGlobalObj;
88 mutable std::mutex mtx;
89 jobject object;
90
91public:
92 static inline void check(jobject object, const char* file, int line) {
93 if( nullptr == object ) {
94 throw jau::RuntimeException("JNIGlobalRef::check: Null jobject", file, line);
95 }
96 }
97
98 /* Creates a GlobalRef using a nullptr for API convenience, lazy assignment. */
99 JNIGlobalRef() noexcept;
100
101 /* Creates a GlobalRef from an object passed to it */
102 JNIGlobalRef(jobject object);
103
106
107 JNIGlobalRef& operator=(const JNIGlobalRef &o);
108 JNIGlobalRef& operator=(JNIGlobalRef &&o) noexcept;
109
110 /* Deletes the stored GlobalRef */
111 ~JNIGlobalRef() noexcept;
112
113 /**
114 * Should return JNIGlobalRefType if the `object` is valid or JNIInvalidRefType if the `object` is nullptr.
115 */
116 jobjectRefType getObjectRefType() const noexcept;
117 bool isValidReference() const noexcept { return getObjectRefType() != JNIInvalidRefType; }
118
119 /* Provides access to the stored GlobalRef as an jobject. */
120 jobject operator*() noexcept;
121
122 /* Provides access to the stored GlobalRef as an jobject. */
123 jobject getObject() const noexcept;
124
125 /* Provides access to the stored GlobalRef as a jclass. */
126 jclass getClass() const noexcept { return (jclass)getObject(); }
127
128 bool operator==(const JNIGlobalRef& rhs) const noexcept;
129
130 bool operator!=(const JNIGlobalRef& rhs) const noexcept
131 { return !( *this == rhs ); }
132};
133
134/*
135 * This class provides a lifetime-managed 'PrimitiveArrayCritical' pinned heap,
136 * which is automatically released when it goes out of scope.
137 * <p>
138 * RAII-style acquire and relinquish via destructor
139 * </p>
140 */
141template <typename T, typename U>
143public:
144 enum Mode : jint {
145 /** Like default 0: If 'isCopy': Update the java array data with the copy and free the copy. */
147
148 /** Like JNI_COMMIT: If 'isCopy': Update the java array data with the copy, but do not free the copy. */
149 UPDATE_NO_RELEASE = JNI_COMMIT,
150
151 /** Like default JNI_ABORT: If 'isCopy': Do not update the java array data with the copy, but free the copy. */
153 };
154
155private:
156 JNIEnv *env;
158 U jarray = nullptr;
159 T* narray = nullptr;
160 jboolean isCopy = false;
161
162public:
163 JNICriticalArray(JNIEnv *env_val) : env(env_val) {}
164
169
170 /**
171 * Release the acquired primitive array, RAII style.
172 */
174 release();
175 }
176
177 /**
178 * Manual release of the acquired primitive array,
179 * usually one likes to simply do this via the destructor, RAII style.
180 */
181 void release() {
182 if( nullptr != narray ) {
183 env->ReleasePrimitiveArrayCritical(jarray, narray, mode);
184 this->jarray = nullptr;
185 this->narray = nullptr;
186 this->env = nullptr;
187 }
188 }
189
190 /**
191 * Acquired the primitive array.
192 */
193 T* get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE) {
194 if( nullptr == jarray_val ) {
195 return nullptr;
196 }
197 T* _narray = static_cast<T*>( env->GetPrimitiveArrayCritical(jarray_val, &isCopy) );
198 if( nullptr != _narray ) {
199 this->mode = mode_val;
200 this->jarray = jarray_val;
201 this->narray = _narray;
202 return _narray;
203 }
204 return nullptr;
205 }
206
207 /**
208 * Returns true if the primitive array had been acquired
209 * and the JVM utilizes a copy of the underlying java array.
210 */
211 bool getIsCopy() const { return isCopy; }
212};
213
214/**@}*/
215
216} /* namespace jau */
217
218#endif /* JAU_JNIMEM__HPP_ */
219
@ NO_UPDATE_AND_RELEASE
Like default JNI_ABORT: If 'isCopy': Do not update the java array data with the copy,...
Definition: jni_mem.hpp:152
@ UPDATE_NO_RELEASE
Like JNI_COMMIT: If 'isCopy': Update the java array data with the copy, but do not free the copy.
Definition: jni_mem.hpp:149
@ UPDATE_AND_RELEASE
Like default 0: If 'isCopy': Update the java array data with the copy and free the copy.
Definition: jni_mem.hpp:146
JNICriticalArray(const JNICriticalArray &o)=delete
JNICriticalArray & operator=(JNICriticalArray &&o)=delete
JNICriticalArray & operator=(const JNICriticalArray &o)=delete
void release()
Manual release of the acquired primitive array, usually one likes to simply do this via the destructo...
Definition: jni_mem.hpp:181
~JNICriticalArray()
Release the acquired primitive array, RAII style.
Definition: jni_mem.hpp:173
T * get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE)
Acquired the primitive array.
Definition: jni_mem.hpp:193
JNICriticalArray(JNIEnv *env_val)
Definition: jni_mem.hpp:163
JNICriticalArray(JNICriticalArray &&o)=delete
bool getIsCopy() const
Returns true if the primitive array had been acquired and the JVM utilizes a copy of the underlying j...
Definition: jni_mem.hpp:211
jobjectRefType getObjectRefType() const noexcept
Should return JNIGlobalRefType if the object is valid or JNIInvalidRefType if the object is nullptr.
jobject getObject() const noexcept
bool operator!=(const JNIGlobalRef &rhs) const noexcept
Definition: jni_mem.hpp:130
static void check(jobject object, const char *file, int line)
Definition: jni_mem.hpp:92
jobject operator*() noexcept
jclass getClass() const noexcept
Definition: jni_mem.hpp:126
bool isValidReference() const noexcept
Definition: jni_mem.hpp:117
bool operator==(const JNIGlobalRef &rhs) const noexcept
Implementation for JavaAnon, by simply wrapping a JNIGlobalRef instance.
Definition: helper_jni.hpp:166
thread_local JNIEnvContainer jni_env
JavaVM * vm