-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathJUCE-support-Android-thread-via-dalvik-juce7.patch
98 lines (91 loc) · 4.03 KB
/
JUCE-support-Android-thread-via-dalvik-juce7.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
diff --git a/modules/juce_core/native/juce_android_JNIHelpers.h b/modules/juce_core/native/juce_android_JNIHelpers.h
index aeb49f97b..e03984205 100644
--- a/modules/juce_core/native/juce_android_JNIHelpers.h
+++ b/modules/juce_core/native/juce_android_JNIHelpers.h
@@ -796,6 +796,15 @@ DECLARE_JNI_CLASS (AndroidSurfaceView, "android/view/SurfaceView")
DECLARE_JNI_CLASS (AndroidSurfaceHolder, "android/view/SurfaceHolder")
#undef JNI_CLASS_MEMBERS
+#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
+ METHOD (constructor1, "<init>", "(Ljava/lang/Runnable;)V") \
+ METHOD (constructor2, "<init>", "(Ljava/lang/Runnable;Ljava/lang/String;)V") \
+ METHOD (start, "start", "()V") \
+
+DECLARE_JNI_CLASS (JavaLangThread, "java/lang/Thread")
+#undef JNI_CLASS_MEMBERS
+
+
//==============================================================================
namespace
{
@@ -992,6 +1001,32 @@ private:
}
};
+//==============================================================================
+class ThreadTargetRunnable : public AndroidInterfaceImplementer
+{
+ Thread *juce_thread;
+ std::function<void*(void* userData)> threadEntryProc;
+public:
+ ThreadTargetRunnable(Thread *juceThread, std::function<void*(void* userData)> threadEntryProc) : juce_thread(juceThread), threadEntryProc(threadEntryProc) {}
+
+ jobject invoke (jobject proxy, jobject method, jobjectArray args) override
+ {
+ auto* env = getEnv();
+
+ auto methodName = juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
+
+ if (methodName == "run")
+ {
+ juce_thread->threadHandle = (void*) pthread_self();
+ juce_thread->threadId = (Thread::ThreadID) juce_thread->threadHandle;
+ threadEntryProc(juce_thread);
+ return nullptr;
+ }
+
+ return AndroidInterfaceImplementer::invoke (proxy, method, args);
+ }
+};
+
//==============================================================================
class FragmentOverlay
{
diff --git a/modules/juce_core/native/juce_android_Threads.cpp b/modules/juce_core/native/juce_android_Threads.cpp
index fe6088553..95d157c72 100644
--- a/modules/juce_core/native/juce_android_Threads.cpp
+++ b/modules/juce_core/native/juce_android_Threads.cpp
@@ -400,7 +400,16 @@ bool Thread::createNativeThread (Priority)
}
PosixThreadAttribute attr { threadStackSize };
- threadId = threadHandle = makeThreadHandle (attr, this, threadEntryProc);
+
+ auto env = getEnv();
+ auto runnableNative = new ThreadTargetRunnable(this, threadEntryProc);
+ auto runnable = CreateJavaInterface(runnableNative, "java/lang/Runnable");
+ GlobalRef threadRunnableGRef { runnable };
+ auto name = env->NewStringUTF("ThreadTargetRunnable");
+ auto threadObj = env->NewObject(JavaLangThread, JavaLangThread.constructor1, threadRunnableGRef.get(), name);
+ auto threadGRef = env->NewGlobalRef(LocalRef<jobject>(threadObj));
+ env->CallVoidMethod(threadGRef, JavaLangThread.start);
+ threadId = threadHandle = threadGRef;
return threadId != nullptr;
}
diff --git a/modules/juce_core/threads/juce_Thread.h b/modules/juce_core/threads/juce_Thread.h
index 97b66ff6f..5492f5f3c 100644
--- a/modules/juce_core/threads/juce_Thread.h
+++ b/modules/juce_core/threads/juce_Thread.h
@@ -457,6 +457,7 @@ protected:
bool setPriority (Priority newPriority);
private:
+ friend class ThreadTargetRunnable; // needs to access threadHandle
//==============================================================================
const String threadName;
std::atomic<void*> threadHandle { nullptr };
@@ -470,6 +471,9 @@ private:
std::atomic<bool> shouldExit { false };
ListenerList<Listener, Array<Listener*, CriticalSection>> listeners;
+ #if JUCE_ANDROID
+ /*GlobalRef*/ void* javaThreadPeer { nullptr };
+ #endif
#if JUCE_ANDROID || JUCE_LINUX || JUCE_BSD
std::atomic<Priority> priority;
#endif