AVPKit
JNIHelper.h
1 /*******************************************************************************
2  * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved.
3  *
4  * This file is part of AVPKit.
5  *
6  * AVPKit is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * AVPKit is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with AVPKit. If not, see <http://www.gnu.org/licenses/>.
18  *******************************************************************************/
19 
20 #ifndef JNIHELPER_H_
21 #define JNIHELPER_H_
22 
23 #include <list>
24 
25 #include <com/avpkit/ferry/Ferry.h>
26 #include <inttypes.h>
27 
28 namespace com { namespace avpkit { namespace ferry {
36 class JNIHelper
37  {
38  public:
39  typedef void (*CallbackFunc)(JavaVM* jvm, void* closure);
40 
41  static VS_API_FERRY JNIHelper* getHelper();
42 
43  // Static convenience methods
44  inline static JavaVM* sGetVM()
45  {
46  return getHelper()->getVM();
47  }
48  inline static void sSetVM(JavaVM *jvm)
49  {
50  getHelper()->setVM(jvm);
51  }
52  inline static jint sGetJNIVersion()
53  {
54  return getHelper()->getJNIVersion();
55  }
56  inline static JNIEnv *sGetEnv()
57  {
58  return getHelper()->getEnv();
59  }
60  inline static void *sGetPointer(jobject pointerRef)
61  {
62  return getHelper()->getPointer(pointerRef);
63  }
64  inline static void *sSetPointer(jobject pointerRef, void *newVal)
65  {
66  return getHelper()->setPointer(pointerRef, newVal);
67  }
68  inline static jobject sNewLocalRef(jobject ref)
69  {
70  return getHelper()->newLocalRef(ref);
71  }
72  inline static void sDeleteLocalRef(jobject ref)
73  {
74  return getHelper()->deleteLocalRef(ref);
75  }
76  inline static jobject sNewGlobalRef(jobject ref)
77  {
78  return getHelper()->newGlobalRef(ref);
79  }
80  inline static void sDeleteGlobalRef(jobject ref)
81  {
82  return getHelper()->deleteGlobalRef(ref);
83  }
84  inline static jweak sNewWeakGlobalRef(jobject ref)
85  {
86  return getHelper()->newWeakGlobalRef(ref);
87  }
88  inline static void sDeleteWeakGlobalRef(jweak ref)
89  {
90  return getHelper()->deleteWeakGlobalRef(ref);
91  }
92  inline static void sRegisterInitializationCallback(
93  CallbackFunc func, void* closure)
94  {
95  return getHelper()->registerInitializationCallback(func, closure);
96  }
97  inline static void sRegisterTerminationCallback(
98  CallbackFunc func, void* closure)
99  {
100  return getHelper()->registerTerminationCallback(func, closure);
101  }
102  // Actual methods
103  VS_API_FERRY JavaVM* getVM();
104  VS_API_FERRY void setVM(JavaVM* jvm);
105 
106  VS_API_FERRY void * getPointer(jobject pointerRef);
107  VS_API_FERRY void * setPointer(jobject pointerRef, void *newVal);
108 
109  VS_API_FERRY jobject newLocalRef(jobject ref);
110  VS_API_FERRY void deleteLocalRef(jobject ref);
111  VS_API_FERRY jobject newGlobalRef(jobject ref);
112  VS_API_FERRY void deleteGlobalRef(jobject ref);
113  VS_API_FERRY jweak newWeakGlobalRef(jobject ref);
114  VS_API_FERRY void deleteWeakGlobalRef(jweak ref);
115 
116  VS_API_FERRY jint getJNIVersion();
117  VS_API_FERRY JNIEnv* getEnv();
118 
119  /*
120  * Register a callback function to be called when the JNIHelper
121  * gets a JavaVM context passed to it. The JNIHelper will also
122  * pass back to the callback the closure value registered with
123  * the callback.
124  *
125  * NOTE: If the JNIHelper already has a JavaVM registered, it will
126  * call the callback WHILE REGISTERING. Be aware of this semantic
127  * and deal accordingly.
128  */
129  VS_API_FERRY void registerInitializationCallback(CallbackFunc, void* closure);
130  VS_API_FERRY void registerTerminationCallback(CallbackFunc, void*closure);
131 
132  VS_API_FERRY virtual ~JNIHelper();
133 
134  /*
135  * This method is not meant for general calling. A program that
136  * is DAMN SURE it never needs to use the helper again can
137  * call it, and we will delete memory.
138  *
139  * Really, the only use case for this is testing that our memory
140  * clean-up code does work.
141  */
142  VS_API_FERRY static void shutdownHelper();
143  /*
144  * This needs to be public for the stupid auto_ptr to work,
145  * but don't go creating one of these and expecting things to
146  * work.
147  */
148  VS_API_FERRY JNIHelper();
149 
150  /*
151  * Added for 2.1
152  */
153 
154  VS_API_FERRY void throwOutOfMemoryError();
155 
156  VS_API_FERRY int32_t isInterrupted();
157 
158  VS_API_FERRY bool isInterruptedException(jthrowable exception);
159 
160  VS_API_FERRY void interrupt();
161 
162  private:
163 
164  JavaVM* mCachedVM;
165  jint mVersion;
166 
167  jweak mJNIPointerReference_class;
168  jmethodID mJNIPointerReference_setPointer_mid;
169  jmethodID mJNIPointerReference_getPointer_mid;
170  jthrowable mOutOfMemoryErrorSingleton;
171 
172  struct CallbackHelper {
173  CallbackFunc mCallback;
174  void* mClosure;
175  };
176  static void addCallback(std::list<CallbackHelper*>*, CallbackFunc, void*closure);
177  static void processCallbacks(std::list<CallbackHelper*>*, JavaVM*, bool execFunc=true);
178  std::list<CallbackHelper*> mInitializationCallbacks;
179  std::list<CallbackHelper*> mTerminationCallbacks;
180 
181  void waitForDebugger(JNIEnv*);
182 
183  static JNIHelper* sSingleton;
184  static volatile bool sDebuggerAttached;
185 
186  jweak mThread_class;
187  jmethodID mThread_isInterrupted_mid;
188  jmethodID mThread_currentThread_mid;
189  jmethodID mThread_interrupt_mid;
190 
191  jweak mInterruptedException_class;
192  };
193 }}}
194 
195 #endif /*JNIHELPER_H_*/
The JNIHelper object contains a series of methods designed to assist functions when running inside a ...
Definition: JNIHelper.h:37
VS_API_FERRY void throwOutOfMemoryError()
Definition: JNIHelper.cpp:514
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...