Modernize Thread

- Based on C++11's `thread` and `thread_local`
- No more need to allocate-deallocate or check for null
- No pointer anymore, just a member variable
- Platform-specific implementations no longer needed (except for the few cases of non-portable functions)
- Simpler for `NO_THREADS`
- Thread ids are now the same across platforms (main is 1; others follow)
This commit is contained in:
Pedro J. Estébanez
2021-01-19 13:29:41 +01:00
parent 6ddfc8e718
commit 99fe462452
87 changed files with 385 additions and 1056 deletions

View File

@@ -267,12 +267,13 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann
job_queue.num_tasks = static_cast<uint32_t>(tasks.size());
for (int i = 0; i < num_job_threads; i++) {
threads_wb[i] = Thread::create(_digest_job_queue, &job_queue);
threads_wb[i] = memnew(Thread);
threads_wb[i]->start(_digest_job_queue, &job_queue);
}
_digest_job_queue(&job_queue);
for (int i = 0; i < num_job_threads; i++) {
Thread::wait_to_finish(threads_wb[i]);
threads_wb[i]->wait_to_finish();
memdelete(threads_wb[i]);
}
}

View File

@@ -48,7 +48,7 @@ extern "C" {
JNIEnv *GDAPI godot_android_get_env() {
#ifdef __ANDROID__
return ThreadAndroid::get_env();
return get_jni_env();
#else
return nullptr;
#endif

View File

@@ -36,7 +36,6 @@
#include "editor/editor_node.h"
GDScriptLanguageServer::GDScriptLanguageServer() {
thread = nullptr;
thread_running = false;
started = false;
@@ -87,9 +86,8 @@ void GDScriptLanguageServer::start() {
if (protocol.start(port, IP_Address("127.0.0.1")) == OK) {
EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR);
if (use_thread) {
ERR_FAIL_COND(thread != nullptr);
thread_running = true;
thread = Thread::create(GDScriptLanguageServer::thread_main, this);
thread.start(GDScriptLanguageServer::thread_main, this);
}
set_process_internal(!use_thread);
started = true;
@@ -98,11 +96,9 @@ void GDScriptLanguageServer::start() {
void GDScriptLanguageServer::stop() {
if (use_thread) {
ERR_FAIL_COND(nullptr == thread);
ERR_FAIL_COND(!thread.is_started());
thread_running = false;
Thread::wait_to_finish(thread);
memdelete(thread);
thread = nullptr;
thread.wait_to_finish();
}
protocol.stop();
started = false;

View File

@@ -40,7 +40,7 @@ class GDScriptLanguageServer : public EditorPlugin {
GDScriptLanguageProtocol protocol;
Thread *thread;
Thread thread;
bool thread_running;
bool started;
bool use_thread;

View File

@@ -109,7 +109,7 @@ bool jni_exception_check(JNIEnv *p_env) {
String app_native_lib_dir_cache;
String determine_app_native_lib_dir() {
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> activityThreadClass(env, env->FindClass("android/app/ActivityThread"));
jmethodID currentActivityThread = env->GetStaticMethodID(activityThreadClass, "currentActivityThread", "()Landroid/app/ActivityThread;");
@@ -253,7 +253,7 @@ int32_t get_build_version_sdk_int() {
// android.os.Build.VERSION.SDK_INT
if (build_version_sdk_int == 0) {
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
jclass versionClass = env->FindClass("android/os/Build$VERSION");
ERR_FAIL_NULL_V(versionClass, 0);
@@ -281,7 +281,7 @@ MonoBoolean _gd_mono_init_cert_store() {
// return false;
// }
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore"));
@@ -322,7 +322,7 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
return nullptr;
}
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
ScopedLocalRef<jstring> js_alias(env, env->NewStringUTF(alias_utf8));
mono_free(alias_utf8);
@@ -380,7 +380,7 @@ void cleanup() {
if (godot_dl_handle)
gd_mono_android_dlclose(godot_dl_handle, nullptr);
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
if (certStore) {
env->DeleteGlobalRef(certStore);
@@ -437,7 +437,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_up_state(const char
*r_is_up = 0;
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
ERR_FAIL_NULL_V(networkInterfaceClass, 0);
@@ -469,7 +469,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_supports_multicast(
*r_supports_multicast = 0;
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
ERR_FAIL_NULL_V(networkInterfaceClass, 0);
@@ -507,7 +507,7 @@ static void interop_get_active_network_dns_servers(char **r_dns_servers, int *dn
CRASH_COND(get_build_version_sdk_int() < 23);
#endif
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
GodotJavaWrapper *godot_java = ((OS_Android *)OS::get_singleton())->get_godot_java();
jobject activity = godot_java->get_activity();
@@ -648,7 +648,7 @@ GD_PINVOKE_EXPORT const char *_monodroid_timezone_get_default_id() {
//
// TimeZone.getDefault().getID()
JNIEnv *env = ThreadAndroid::get_env();
JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> timeZoneClass(env, env->FindClass("java/util/TimeZone"));
ERR_FAIL_NULL_V(timeZoneClass, nullptr);

View File

@@ -34,7 +34,6 @@
NoiseTexture::NoiseTexture() {
update_queued = false;
noise_thread = nullptr;
regen_queued = false;
first_time = true;
@@ -52,10 +51,7 @@ NoiseTexture::~NoiseTexture() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
if (noise_thread) {
Thread::wait_to_finish(noise_thread);
memdelete(noise_thread);
}
noise_thread.wait_to_finish();
}
void NoiseTexture::_bind_methods() {
@@ -109,11 +105,9 @@ void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
_set_texture_data(p_image);
Thread::wait_to_finish(noise_thread);
memdelete(noise_thread);
noise_thread = nullptr;
noise_thread.wait_to_finish();
if (regen_queued) {
noise_thread = Thread::create(_thread_function, this);
noise_thread.start(_thread_function, this);
regen_queued = false;
}
}
@@ -165,8 +159,8 @@ void NoiseTexture::_update_texture() {
use_thread = false;
#endif
if (use_thread) {
if (!noise_thread) {
noise_thread = Thread::create(_thread_function, this);
if (!noise_thread.is_started()) {
noise_thread.start(_thread_function, this);
regen_queued = false;
} else {
regen_queued = true;

View File

@@ -45,7 +45,7 @@ class NoiseTexture : public Texture2D {
private:
Ref<Image> data;
Thread *noise_thread;
Thread noise_thread;
bool first_time;
bool update_queued;

View File

@@ -140,9 +140,7 @@ void VideoStreamPlaybackTheora::clear() {
#ifdef THEORA_USE_THREAD_STREAMING
thread_exit = true;
thread_sem->post(); //just in case
Thread::wait_to_finish(thread);
memdelete(thread);
thread = nullptr;
thread.wait_to_finish();
ring_buffer.clear();
#endif
@@ -181,7 +179,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
int read = file->get_buffer(read_buffer.ptr(), to_read);
ring_buffer.write(read_buffer.ptr(), read);
thread = Thread::create(_streaming_thread, this);
thread.start(_streaming_thread, this);
#endif
@@ -669,7 +667,6 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
ring_buffer.resize(rb_power);
read_buffer.resize(RB_SIZE_KB * 1024);
thread_sem = Semaphore::create();
thread = nullptr;
thread_exit = false;
thread_eof = false;

View File

@@ -112,7 +112,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
Vector<uint8_t> read_buffer;
bool thread_eof;
Semaphore *thread_sem;
Thread *thread;
Thread thread;
volatile bool thread_exit;
static void _streaming_thread(void *ud);