jaulib v1.3.6
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
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 <mutex>
34
35#include <jau/basic_types.hpp>
36
37namespace jau::jni {
38
39/** \addtogroup JavaVM
40 *
41 * @{
42 */
43
44extern JavaVM* vm;
45
46
47/*
48 * This class provides a lifetime-managed JNIEnv object, which attaches or
49 * detaches the current thread from the JVM automatically
50 */
52private:
53 JNIEnv *env = nullptr;
54 bool needsDetach = false;
55
56public:
57 /* Attaches this thread to the JVM if it is not already attached */
59 /* Detaches this thread to the JVM if it is attached */
61
62 /* Provides access to the local thread's JNIEnv object */
63 JNIEnv *operator*();
64 /* Provides access to the local thread's JNIEnv object's methods */
65 JNIEnv *operator->();
66
67 /* Attaches this thread to the JVM if it is not already attached */
68 void attach();
69 /* Detaches this thread to the JVM if it is attached */
70 void detach();
71};
72
73/* Each thread has a local jni_env variable of JNIEnvContainer type */
74extern thread_local JNIEnvContainer jni_env;
75
76class JavaGlobalObj; // fwd
77
78/*
79 * This class provides a lifetime-managed GlobalRef variable,
80 * which is automatically deleted when it goes out of scope.
81 *
82 * RAII-style acquire and relinquish via destructor
83 */
85private:
86 friend class JavaGlobalObj;
87 mutable std::mutex mtx;
88 jobject object;
89
90public:
91 static inline void check(jobject object, const char* file, int line) {
92 if( nullptr == object ) {
93 throw jau::RuntimeException("JNIGlobalRef::check: Null jobject", file, line);
94 }
95 }
96
97 /* Creates a GlobalRef using a nullptr for API convenience, lazy assignment. */
98 JNIGlobalRef() noexcept;
99
100 /* Creates a GlobalRef from an object passed to it */
101 JNIGlobalRef(jobject object);
102
105
106 JNIGlobalRef& operator=(const JNIGlobalRef &o);
107 JNIGlobalRef& operator=(JNIGlobalRef &&o) noexcept;
108
109 /* Deletes the stored GlobalRef */
110 ~JNIGlobalRef() noexcept;
111
112 /**
113 * Should return JNIGlobalRefType if the `object` is valid or JNIInvalidRefType if the `object` is nullptr.
114 */
115 jobjectRefType getObjectRefType() const noexcept;
116 bool isValidReference() const noexcept { return getObjectRefType() != JNIInvalidRefType; }
117
118 /* Provides access to the stored GlobalRef as an jobject. */
119 jobject operator*() noexcept;
120
121 /* Provides access to the stored GlobalRef as an jobject. */
122 jobject getObject() const noexcept;
123
124 /* Provides access to the stored GlobalRef as a jclass. */
125 jclass getClass() const noexcept { return (jclass)getObject(); }
126
127 bool operator==(const JNIGlobalRef& rhs) const noexcept;
128
129 bool operator!=(const JNIGlobalRef& rhs) const noexcept
130 { return !( *this == rhs ); }
131};
132
133/*
134 * This class provides a lifetime-managed 'PrimitiveArrayCritical' pinned heap,
135 * which is automatically released when it goes out of scope.
136 * <p>
137 * RAII-style acquire and relinquish via destructor
138 * </p>
139 */
140template <typename T, typename U>
142public:
143 enum Mode : jint {
144 /** Like default 0: If 'isCopy': Update the java array data with the copy and free the copy. */
146
147 /** Like JNI_COMMIT: If 'isCopy': Update the java array data with the copy, but do not free the copy. */
148 UPDATE_NO_RELEASE = JNI_COMMIT,
149
150 /** Like default JNI_ABORT: If 'isCopy': Do not update the java array data with the copy, but free the copy. */
152 };
153
154private:
155 JNIEnv *env;
157 U jarray = nullptr;
158 T* narray = nullptr;
159 jboolean isCopy = false;
160
161public:
162 JNICriticalArray(JNIEnv *env_val) : env(env_val) {}
163
168
169 /**
170 * Release the acquired primitive array, RAII style.
171 */
173 release();
174 }
175
176 /**
177 * Manual release of the acquired primitive array,
178 * usually one likes to simply do this via the destructor, RAII style.
179 */
180 void release() {
181 if( nullptr != narray ) {
182 env->ReleasePrimitiveArrayCritical(jarray, narray, mode);
183 this->jarray = nullptr;
184 this->narray = nullptr;
185 this->env = nullptr;
186 }
187 }
188
189 /**
190 * Acquired the primitive array.
191 */
192 T* get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE) {
193 if( nullptr == jarray_val ) {
194 return nullptr;
195 }
196 T* _narray = static_cast<T*>( env->GetPrimitiveArrayCritical(jarray_val, &isCopy) );
197 if( nullptr != _narray ) {
198 this->mode = mode_val;
199 this->jarray = jarray_val;
200 this->narray = _narray;
201 return _narray;
202 }
203 return nullptr;
204 }
205
206 /**
207 * Returns true if the primitive array had been acquired
208 * and the JVM utilizes a copy of the underlying java array.
209 */
210 bool getIsCopy() const { return isCopy; }
211};
212
213/**@}*/
214
215} /* namespace jau */
216
217#endif /* JAU_JNIMEM__HPP_ */
218
@ NO_UPDATE_AND_RELEASE
Like default JNI_ABORT: If 'isCopy': Do not update the java array data with the copy,...
Definition jni_mem.hpp:151
@ 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:148
@ UPDATE_AND_RELEASE
Like default 0: If 'isCopy': Update the java array data with the copy and free the copy.
Definition jni_mem.hpp:145
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:180
~JNICriticalArray()
Release the acquired primitive array, RAII style.
Definition jni_mem.hpp:172
T * get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE)
Acquired the primitive array.
Definition jni_mem.hpp:192
JNICriticalArray(JNIEnv *env_val)
Definition jni_mem.hpp:162
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:210
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:129
static void check(jobject object, const char *file, int line)
Definition jni_mem.hpp:91
jobject operator*() noexcept
jclass getClass() const noexcept
Definition jni_mem.hpp:125
bool isValidReference() const noexcept
Definition jni_mem.hpp:116
friend class JavaGlobalObj
Definition jni_mem.hpp:86
bool operator==(const JNIGlobalRef &rhs) const noexcept
Implementation for JavaAnon, by simply wrapping a JNIGlobalRef instance.
thread_local JNIEnvContainer jni_env
JavaVM * vm