2
0
Эх сурвалжийг харах

Modernize Mutex

- Based on C++11's `mutex`
- No more need to allocate-deallocate or check for null
- No pointer anymore, just a member variable
- Platform-specific implementations no longer needed
- Simpler for `NO_THREADS`
- `BinaryMutex` added for special cases as the non-recursive version
- `MutexLock` now takes a reference. At this point the cases of null `Mutex`es are rare. If you ever need that, just don't use `MutexLock`.
- `ScopedMutexLock` is dropped and replaced by `MutexLock`, because they were pretty much the same.
Pedro J. Estébanez 4 жил өмнө
parent
commit
4ddcdc031b
99 өөрчлөгдсөн 467 нэмэгдсэн , 1386 устгасан
  1. 3 13
      core/bind/core_bind.cpp
  2. 1 4
      core/bind/core_bind.h
  3. 2 6
      core/command_queue_mt.cpp
  4. 1 1
      core/command_queue_mt.h
  5. 11 17
      core/io/file_access_network.cpp
  6. 3 3
      core/io/file_access_network.h
  7. 19 21
      core/io/ip.cpp
  8. 7 27
      core/io/resource_loader.cpp
  9. 1 2
      core/io/resource_loader.h
  10. 9 21
      core/os/mutex.cpp
  11. 71 24
      core/os/mutex.h
  12. 0 2
      core/os/os.h
  13. 0 8
      core/os/thread_dummy.cpp
  14. 0 12
      core/os/thread_dummy.h
  15. 0 49
      core/os/thread_safe.cpp
  16. 4 45
      core/os/thread_safe.h
  17. 2 5
      core/pool_vector.cpp
  18. 19 19
      core/pool_vector.h
  19. 1 9
      core/register_core_types.cpp
  20. 23 27
      core/string_name.cpp
  21. 1 1
      core/string_name.h
  22. 4 11
      drivers/alsa/audio_driver_alsa.cpp
  23. 1 1
      drivers/alsa/audio_driver_alsa.h
  24. 2 11
      drivers/alsamidi/midi_driver_alsamidi.cpp
  25. 1 1
      drivers/alsamidi/midi_driver_alsamidi.h
  26. 3 15
      drivers/coreaudio/audio_driver_coreaudio.cpp
  27. 1 1
      drivers/coreaudio/audio_driver_coreaudio.h
  28. 4 10
      drivers/pulseaudio/audio_driver_pulseaudio.cpp
  29. 1 1
      drivers/pulseaudio/audio_driver_pulseaudio.h
  30. 0 73
      drivers/unix/mutex_posix.cpp
  31. 0 61
      drivers/unix/mutex_posix.h
  32. 3 9
      drivers/unix/os_unix.cpp
  33. 2 11
      drivers/wasapi/audio_driver_wasapi.cpp
  34. 1 1
      drivers/wasapi/audio_driver_wasapi.h
  35. 0 101
      drivers/windows/mutex_windows.cpp
  36. 0 63
      drivers/windows/mutex_windows.h
  37. 4 8
      drivers/xaudio2/audio_driver_xaudio2.cpp
  38. 1 1
      drivers/xaudio2/audio_driver_xaudio2.h
  39. 3 5
      editor/editor_node.cpp
  40. 1 1
      editor/editor_node.h
  41. 14 16
      editor/editor_resource_preview.cpp
  42. 1 1
      editor/editor_resource_preview.h
  43. 6 8
      editor/fileserver/editor_file_server.cpp
  44. 1 1
      editor/fileserver/editor_file_server.h
  45. 9 15
      editor/import/resource_importer_texture.cpp
  46. 1 2
      editor/import/resource_importer_texture.h
  47. 4 28
      modules/gdnative/nativescript/nativescript.cpp
  48. 2 4
      modules/gdnative/nativescript/nativescript.h
  49. 2 26
      modules/gdnative/pluginscript/pluginscript_language.cpp
  50. 2 2
      modules/gdnative/pluginscript/pluginscript_language.h
  51. 30 106
      modules/gdscript/gdscript.cpp
  52. 1 1
      modules/gdscript/gdscript.h
  53. 8 26
      modules/gdscript/gdscript_function.cpp
  54. 14 56
      modules/mono/csharp_script.cpp
  55. 5 5
      modules/mono/csharp_script.h
  56. 1 2
      modules/mono/mono_gd/gd_mono_utils.cpp
  57. 0 67
      modules/mono/utils/mutex_utils.h
  58. 4 18
      modules/visual_script/visual_script.cpp
  59. 1 1
      modules/visual_script/visual_script.h
  60. 5 8
      platform/android/audio_driver_jandroid.cpp
  61. 1 1
      platform/android/audio_driver_jandroid.h
  62. 8 10
      platform/android/audio_driver_opensl.cpp
  63. 1 1
      platform/android/audio_driver_opensl.h
  64. 15 19
      platform/android/export/export.cpp
  65. 3 5
      platform/iphone/export/export.cpp
  66. 2 9
      platform/javascript/audio_driver_javascript.cpp
  67. 1 1
      platform/javascript/audio_driver_javascript.h
  68. 9 11
      platform/javascript/export/export.cpp
  69. 0 2
      platform/uwp/os_uwp.cpp
  70. 0 2
      platform/windows/os_windows.cpp
  71. 8 10
      platform/x11/joypad_linux.cpp
  72. 1 1
      platform/x11/joypad_linux.h
  73. 0 4
      platform/x11/os_x11.cpp
  74. 1 1
      platform/x11/os_x11.h
  75. 9 25
      scene/2d/canvas_item.cpp
  76. 1 1
      scene/2d/canvas_item.h
  77. 6 28
      scene/2d/cpu_particles_2d.cpp
  78. 1 1
      scene/2d/cpu_particles_2d.h
  79. 7 26
      scene/3d/cpu_particles.cpp
  80. 1 1
      scene/3d/cpu_particles.h
  81. 8 10
      scene/debugger/script_debugger_remote.cpp
  82. 1 1
      scene/debugger/script_debugger_remote.h
  83. 9 18
      scene/resources/dynamic_font.cpp
  84. 1 1
      scene/resources/dynamic_font.h
  85. 9 25
      scene/resources/material.cpp
  86. 1 1
      scene/resources/material.h
  87. 9 25
      scene/resources/particles_material.cpp
  88. 1 1
      scene/resources/particles_material.h
  89. 4 8
      servers/audio/audio_driver_dummy.cpp
  90. 1 1
      servers/audio/audio_driver_dummy.h
  91. 5 7
      servers/audio_server.cpp
  92. 1 1
      servers/audio_server.h
  93. 0 2
      servers/physics_2d/physics_2d_server_wrap_mt.cpp
  94. 1 1
      servers/physics_2d/physics_2d_server_wrap_mt.h
  95. 12 12
      servers/server_wrap_mt_common.h
  96. 6 15
      servers/visual/visual_server_scene.cpp
  97. 1 1
      servers/visual/visual_server_scene.h
  98. 0 2
      servers/visual/visual_server_wrap_mt.cpp
  99. 1 1
      servers/visual/visual_server_wrap_mt.h

+ 3 - 13
core/bind/core_bind.cpp

@@ -2717,17 +2717,17 @@ _Semaphore::~_Semaphore() {
 
 void _Mutex::lock() {
 
-	mutex->lock();
+	mutex.lock();
 }
 
 Error _Mutex::try_lock() {
 
-	return mutex->try_lock();
+	return mutex.try_lock();
 }
 
 void _Mutex::unlock() {
 
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void _Mutex::_bind_methods() {
@@ -2737,16 +2737,6 @@ void _Mutex::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock);
 }
 
-_Mutex::_Mutex() {
-
-	mutex = Mutex::create();
-}
-
-_Mutex::~_Mutex() {
-
-	memdelete(mutex);
-}
-
 ///////////////
 
 void _Thread::_start_func(void *ud) {

+ 1 - 4
core/bind/core_bind.h

@@ -652,7 +652,7 @@ public:
 class _Mutex : public Reference {
 
 	GDCLASS(_Mutex, Reference);
-	Mutex *mutex;
+	Mutex mutex;
 
 	static void _bind_methods();
 
@@ -660,9 +660,6 @@ public:
 	void lock();
 	Error try_lock();
 	void unlock();
-
-	_Mutex();
-	~_Mutex();
 };
 
 class _Semaphore : public Reference {

+ 2 - 6
core/command_queue_mt.cpp

@@ -35,14 +35,12 @@
 
 void CommandQueueMT::lock() {
 
-	if (mutex)
-		mutex->lock();
+	mutex.lock();
 }
 
 void CommandQueueMT::unlock() {
 
-	if (mutex)
-		mutex->unlock();
+	mutex.unlock();
 }
 
 void CommandQueueMT::wait_for_flush() {
@@ -107,7 +105,6 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
 	read_ptr_and_epoch = 0;
 	write_ptr_and_epoch = 0;
 	dealloc_ptr = 0;
-	mutex = Mutex::create();
 
 	command_mem_size = GLOBAL_DEF_RST("memory/limits/command_queue/multithreading_queue_size_kb", DEFAULT_COMMAND_MEM_SIZE_KB);
 	ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/command_queue/multithreading_queue_size_kb", PropertyInfo(Variant::INT, "memory/limits/command_queue/multithreading_queue_size_kb", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"));
@@ -130,7 +127,6 @@ CommandQueueMT::~CommandQueueMT() {
 
 	if (sync)
 		memdelete(sync);
-	memdelete(mutex);
 	for (int i = 0; i < SYNC_SEMAPHORES; i++) {
 
 		memdelete(sync_sems[i].sem);

+ 1 - 1
core/command_queue_mt.h

@@ -321,7 +321,7 @@ class CommandQueueMT {
 	uint32_t dealloc_ptr;
 	uint32_t command_mem_size;
 	SyncSemaphore sync_sems[SYNC_SEMAPHORES];
-	Mutex *mutex;
+	Mutex mutex;
 	Semaphore *sync;
 
 	template <class T>

+ 11 - 17
core/io/file_access_network.cpp

@@ -42,14 +42,14 @@
 
 void FileAccessNetworkClient::lock_mutex() {
 
-	mutex->lock();
+	mutex.lock();
 	lockcount++;
 }
 
 void FileAccessNetworkClient::unlock_mutex() {
 
 	lockcount--;
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void FileAccessNetworkClient::put_32(int p_32) {
@@ -97,7 +97,7 @@ void FileAccessNetworkClient::_thread_func() {
 		lock_mutex();
 		DEBUG_PRINT("MUTEX PASS");
 
-		blockrequest_mutex->lock();
+		blockrequest_mutex.lock();
 		while (block_requests.size()) {
 			put_32(block_requests.front()->get().id);
 			put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
@@ -105,7 +105,7 @@ void FileAccessNetworkClient::_thread_func() {
 			put_32(block_requests.front()->get().size);
 			block_requests.pop_front();
 		}
-		blockrequest_mutex->unlock();
+		blockrequest_mutex.unlock();
 
 		DEBUG_PRINT("THREAD ITER");
 
@@ -225,8 +225,6 @@ FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL;
 FileAccessNetworkClient::FileAccessNetworkClient() {
 
 	thread = NULL;
-	mutex = Mutex::create();
-	blockrequest_mutex = Mutex::create();
 	quit = false;
 	singleton = this;
 	last_id = 0;
@@ -244,8 +242,6 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
 		memdelete(thread);
 	}
 
-	memdelete(blockrequest_mutex);
-	memdelete(mutex);
 	memdelete(sem);
 }
 
@@ -259,10 +255,10 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
 		ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size)));
 	}
 
-	buffer_mutex->lock();
+	buffer_mutex.lock();
 	pages.write[page].buffer = p_block;
 	pages.write[page].queued = false;
-	buffer_mutex->unlock();
+	buffer_mutex.unlock();
 
 	if (waiting_on_page == page) {
 		waiting_on_page = -1;
@@ -385,14 +381,14 @@ void FileAccessNetwork::_queue_page(int p_page) const {
 
 		FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
 
-		nc->blockrequest_mutex->lock();
+		nc->blockrequest_mutex.lock();
 		FileAccessNetworkClient::BlockRequest br;
 		br.id = id;
 		br.offset = size_t(p_page) * page_size;
 		br.size = page_size;
 		nc->block_requests.push_back(br);
 		pages.write[p_page].queued = true;
-		nc->blockrequest_mutex->unlock();
+		nc->blockrequest_mutex.unlock();
 		DEBUG_PRINT("QUEUE PAGE POST");
 		nc->sem->post();
 		DEBUG_PRINT("queued " + itos(p_page));
@@ -418,14 +414,14 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
 		int page = pos / page_size;
 
 		if (page != last_page) {
-			buffer_mutex->lock();
+			buffer_mutex.lock();
 			if (pages[page].buffer.empty()) {
 				waiting_on_page = page;
 				for (int j = 0; j < read_ahead; j++) {
 
 					_queue_page(page + j);
 				}
-				buffer_mutex->unlock();
+				buffer_mutex.unlock();
 				DEBUG_PRINT("wait");
 				page_sem->wait();
 				DEBUG_PRINT("done");
@@ -436,7 +432,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
 					_queue_page(page + j);
 				}
 				//queue pages
-				buffer_mutex->unlock();
+				buffer_mutex.unlock();
 			}
 
 			buff = pages.write[page].buffer.ptrw();
@@ -524,7 +520,6 @@ FileAccessNetwork::FileAccessNetwork() {
 	pos = 0;
 	sem = Semaphore::create();
 	page_sem = Semaphore::create();
-	buffer_mutex = Mutex::create();
 	FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
 	nc->lock_mutex();
 	id = nc->last_id++;
@@ -542,7 +537,6 @@ FileAccessNetwork::~FileAccessNetwork() {
 	close();
 	memdelete(sem);
 	memdelete(page_sem);
-	memdelete(buffer_mutex);
 
 	FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
 	nc->lock_mutex();

+ 3 - 3
core/io/file_access_network.h

@@ -52,8 +52,8 @@ class FileAccessNetworkClient {
 	Semaphore *sem;
 	Thread *thread;
 	bool quit;
-	Mutex *mutex;
-	Mutex *blockrequest_mutex;
+	Mutex mutex;
+	Mutex blockrequest_mutex;
 	Map<int, FileAccessNetwork *> accesses;
 	Ref<StreamPeerTCP> client;
 	int last_id;
@@ -87,7 +87,7 @@ class FileAccessNetwork : public FileAccess {
 
 	Semaphore *sem;
 	Semaphore *page_sem;
-	Mutex *buffer_mutex;
+	Mutex buffer_mutex;
 	bool opened;
 	size_t total_size;
 	mutable size_t pos;

+ 19 - 21
core/io/ip.cpp

@@ -70,7 +70,7 @@ struct _IP_ResolverPrivate {
 		return IP::RESOLVER_INVALID_ID;
 	}
 
-	Mutex *mutex;
+	Mutex mutex;
 	Semaphore *sem;
 
 	Thread *thread;
@@ -100,9 +100,9 @@ struct _IP_ResolverPrivate {
 
 			ipr->sem->wait();
 
-			ipr->mutex->lock();
+			ipr->mutex.lock();
 			ipr->resolve_queues();
-			ipr->mutex->unlock();
+			ipr->mutex.unlock();
 		}
 	}
 
@@ -115,30 +115,30 @@ struct _IP_ResolverPrivate {
 
 IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
 
-	resolver->mutex->lock();
+	resolver->mutex.lock();
 
 	String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
 	if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
 		IP_Address res = resolver->cache[key];
-		resolver->mutex->unlock();
+		resolver->mutex.unlock();
 		return res;
 	}
 
 	IP_Address res = _resolve_hostname(p_hostname, p_type);
 	resolver->cache[key] = res;
-	resolver->mutex->unlock();
+	resolver->mutex.unlock();
 	return res;
 }
 
 IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
 
-	resolver->mutex->lock();
+	resolver->mutex.lock();
 
 	ResolverID id = resolver->find_empty_id();
 
 	if (id == RESOLVER_INVALID_ID) {
 		WARN_PRINT("Out of resolver queries");
-		resolver->mutex->unlock();
+		resolver->mutex.unlock();
 		return id;
 	}
 
@@ -157,7 +157,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
 			resolver->resolve_queues();
 	}
 
-	resolver->mutex->unlock();
+	resolver->mutex.unlock();
 	return id;
 }
 
@@ -165,15 +165,15 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
 
 	ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
 
-	resolver->mutex->lock();
+	resolver->mutex.lock();
 	if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) {
 		ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
-		resolver->mutex->unlock();
+		resolver->mutex.unlock();
 		return IP::RESOLVER_STATUS_NONE;
 	}
 	IP::ResolverStatus res = resolver->queue[p_id].status;
 
-	resolver->mutex->unlock();
+	resolver->mutex.unlock();
 	return res;
 }
 
@@ -181,17 +181,17 @@ IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
 
 	ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
 
-	resolver->mutex->lock();
+	resolver->mutex.lock();
 
 	if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
 		ERR_PRINTS("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
-		resolver->mutex->unlock();
+		resolver->mutex.unlock();
 		return IP_Address();
 	}
 
 	IP_Address res = resolver->queue[p_id].response;
 
-	resolver->mutex->unlock();
+	resolver->mutex.unlock();
 	return res;
 }
 
@@ -199,16 +199,16 @@ void IP::erase_resolve_item(ResolverID p_id) {
 
 	ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
 
-	resolver->mutex->lock();
+	resolver->mutex.lock();
 
 	resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
 
-	resolver->mutex->unlock();
+	resolver->mutex.unlock();
 }
 
 void IP::clear_cache(const String &p_hostname) {
 
-	resolver->mutex->lock();
+	resolver->mutex.lock();
 
 	if (p_hostname.empty()) {
 		resolver->cache.clear();
@@ -219,7 +219,7 @@ void IP::clear_cache(const String &p_hostname) {
 		resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY));
 	}
 
-	resolver->mutex->unlock();
+	resolver->mutex.unlock();
 }
 
 Array IP::_get_local_addresses() const {
@@ -315,7 +315,6 @@ IP::IP() {
 	singleton = this;
 	resolver = memnew(_IP_ResolverPrivate);
 	resolver->sem = NULL;
-	resolver->mutex = Mutex::create();
 
 #ifndef NO_THREADS
 
@@ -349,6 +348,5 @@ IP::~IP() {
 
 #endif
 
-	memdelete(resolver->mutex);
 	memdelete(resolver);
 }

+ 7 - 27
core/io/resource_loader.cpp

@@ -289,9 +289,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
 bool ResourceLoader::_add_to_loading_map(const String &p_path) {
 
 	bool success;
-	if (loading_map_mutex) {
-		loading_map_mutex->lock();
-	}
+	loading_map_mutex.lock();
 
 	LoadingMapKey key;
 	key.path = p_path;
@@ -304,17 +302,13 @@ bool ResourceLoader::_add_to_loading_map(const String &p_path) {
 		success = true;
 	}
 
-	if (loading_map_mutex) {
-		loading_map_mutex->unlock();
-	}
+	loading_map_mutex.unlock();
 
 	return success;
 }
 
 void ResourceLoader::_remove_from_loading_map(const String &p_path) {
-	if (loading_map_mutex) {
-		loading_map_mutex->lock();
-	}
+	loading_map_mutex.lock();
 
 	LoadingMapKey key;
 	key.path = p_path;
@@ -322,15 +316,11 @@ void ResourceLoader::_remove_from_loading_map(const String &p_path) {
 
 	loading_map.erase(key);
 
-	if (loading_map_mutex) {
-		loading_map_mutex->unlock();
-	}
+	loading_map_mutex.unlock();
 }
 
 void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) {
-	if (loading_map_mutex) {
-		loading_map_mutex->lock();
-	}
+	loading_map_mutex.lock();
 
 	LoadingMapKey key;
 	key.path = p_path;
@@ -338,9 +328,7 @@ void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, T
 
 	loading_map.erase(key);
 
-	if (loading_map_mutex) {
-		loading_map_mutex->unlock();
-	}
+	loading_map_mutex.unlock();
 }
 
 RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
@@ -994,15 +982,9 @@ void ResourceLoader::remove_custom_loaders() {
 	}
 }
 
-Mutex *ResourceLoader::loading_map_mutex = NULL;
+Mutex ResourceLoader::loading_map_mutex;
 HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map;
 
-void ResourceLoader::initialize() {
-#ifndef NO_THREADS
-	loading_map_mutex = Mutex::create();
-#endif
-}
-
 void ResourceLoader::finalize() {
 #ifndef NO_THREADS
 	const LoadingMapKey *K = NULL;
@@ -1010,8 +992,6 @@ void ResourceLoader::finalize() {
 		ERR_PRINTS("Exited while resource is being loaded: " + K->path);
 	}
 	loading_map.clear();
-	memdelete(loading_map_mutex);
-	loading_map_mutex = NULL;
 #endif
 }
 

+ 1 - 2
core/io/resource_loader.h

@@ -120,7 +120,7 @@ class ResourceLoader {
 	static ResourceLoadedCallback _loaded_callback;
 
 	static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
-	static Mutex *loading_map_mutex;
+	static Mutex loading_map_mutex;
 
 	//used to track paths being loaded in a thread, avoids cyclic recursion
 	struct LoadingMapKey {
@@ -197,7 +197,6 @@ public:
 	static void add_custom_loaders();
 	static void remove_custom_loaders();
 
-	static void initialize();
 	static void finalize();
 };
 

+ 9 - 21
core/os/mutex.cpp

@@ -30,31 +30,19 @@
 
 #include "mutex.h"
 
-#include "core/error_macros.h"
+static Mutex _global_mutex;
 
-#include <stddef.h>
-
-Mutex *(*Mutex::create_func)(bool) = 0;
-
-Mutex *Mutex::create(bool p_recursive) {
-
-	ERR_FAIL_COND_V(!create_func, 0);
-
-	return create_func(p_recursive);
+void _global_lock() {
+	_global_mutex.lock();
 }
 
-Mutex::~Mutex() {
+void _global_unlock() {
+	_global_mutex.unlock();
 }
 
-Mutex *_global_mutex = NULL;
+#ifndef NO_THREADS
 
-void _global_lock() {
+template class MutexImpl<std::recursive_mutex>;
+template class MutexImpl<std::mutex>;
 
-	if (_global_mutex)
-		_global_mutex->lock();
-}
-void _global_unlock() {
-
-	if (_global_mutex)
-		_global_mutex->unlock();
-}
+#endif

+ 71 - 24
core/os/mutex.h

@@ -32,42 +32,89 @@
 #define MUTEX_H
 
 #include "core/error_list.h"
+#include "core/typedefs.h"
 
-/**
- * @class Mutex
- * @author Juan Linietsky
- * Portable Mutex (thread-safe locking) implementation.
- * Mutexes are always recursive ( they don't self-lock in a single thread ).
- * Mutexes can be used with a Lockp object like this, to avoid having to worry about unlocking:
- * Lockp( mutex );
- */
+#if !defined(NO_THREADS)
 
-class Mutex {
-protected:
-	static Mutex *(*create_func)(bool);
+#include <mutex>
+
+template <class StdMutexT>
+class MutexImpl {
+	mutable StdMutexT mutex;
+	friend class MutexLock;
 
 public:
-	virtual void lock() = 0; ///< Lock the mutex, block if locked by someone else
-	virtual void unlock() = 0; ///< Unlock the mutex, let other threads continue
-	virtual Error try_lock() = 0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock.
+	_ALWAYS_INLINE_ void lock() const {
+		mutex.lock();
+	}
 
-	static Mutex *create(bool p_recursive = true); ///< Create a mutex
+	_ALWAYS_INLINE_ void unlock() const {
+		mutex.unlock();
+	}
 
-	virtual ~Mutex();
+	_ALWAYS_INLINE_ Error try_lock() const {
+		return mutex.try_lock() ? OK : ERR_BUSY;
+	}
 };
 
+// This is written this way instead of being a template to overcome a limitation of C++ pre-17
+// that would require MutexLock to be used like this: MutexLock<Mutex> lock;
 class MutexLock {
-
-	Mutex *mutex;
+	union {
+		std::recursive_mutex *recursive_mutex;
+		std::mutex *mutex;
+	};
+	bool recursive;
 
 public:
-	MutexLock(Mutex *p_mutex) {
-		mutex = p_mutex;
-		if (mutex) mutex->lock();
+	_ALWAYS_INLINE_ explicit MutexLock(const MutexImpl<std::recursive_mutex> &p_mutex) :
+			recursive_mutex(&p_mutex.mutex),
+			recursive(true) {
+		recursive_mutex->lock();
 	}
-	~MutexLock() {
-		if (mutex) mutex->unlock();
+	_ALWAYS_INLINE_ explicit MutexLock(const MutexImpl<std::mutex> &p_mutex) :
+			mutex(&p_mutex.mutex),
+			recursive(false) {
+		mutex->lock();
+	}
+
+	_ALWAYS_INLINE_ ~MutexLock() {
+		if (recursive) {
+			recursive_mutex->unlock();
+		} else {
+			mutex->unlock();
+		}
 	}
 };
 
-#endif
+using Mutex = MutexImpl<std::recursive_mutex>; // Recursive, for general use
+using BinaryMutex = MutexImpl<std::mutex>; // Non-recursive, handle with care
+
+extern template class MutexImpl<std::recursive_mutex>;
+extern template class MutexImpl<std::mutex>;
+
+#else
+
+class FakeMutex {
+	FakeMutex() {}
+};
+
+template <class MutexT>
+class MutexImpl {
+public:
+	_ALWAYS_INLINE_ void lock() const {}
+	_ALWAYS_INLINE_ void unlock() const {}
+	_ALWAYS_INLINE_ Error try_lock() const { return OK; }
+};
+
+class MutexLock {
+public:
+	explicit MutexLock(const MutexImpl<FakeMutex> &p_mutex) {}
+};
+
+using Mutex = MutexImpl<FakeMutex>;
+using BinaryMutex = MutexImpl<FakeMutex>; // Non-recursive, handle with care
+
+#endif // !NO_THREADS
+
+#endif // MUTEX_H

+ 0 - 2
core/os/os.h

@@ -41,8 +41,6 @@
 
 #include <stdarg.h>
 
-class Mutex;
-
 class OS {
 
 	static OS *singleton;

+ 0 - 8
core/os/thread_dummy.cpp

@@ -40,14 +40,6 @@ void ThreadDummy::make_default() {
 	Thread::create_func = &ThreadDummy::create;
 };
 
-Mutex *MutexDummy::create(bool p_recursive) {
-	return memnew(MutexDummy);
-};
-
-void MutexDummy::make_default() {
-	Mutex::create_func = &MutexDummy::create;
-};
-
 Semaphore *SemaphoreDummy::create() {
 	return memnew(SemaphoreDummy);
 };

+ 0 - 12
core/os/thread_dummy.h

@@ -45,18 +45,6 @@ public:
 	static void make_default();
 };
 
-class MutexDummy : public Mutex {
-
-	static Mutex *create(bool p_recursive);
-
-public:
-	virtual void lock(){};
-	virtual void unlock(){};
-	virtual Error try_lock() { return OK; };
-
-	static void make_default();
-};
-
 class SemaphoreDummy : public Semaphore {
 
 	static Semaphore *create();

+ 0 - 49
core/os/thread_safe.cpp

@@ -1,49 +0,0 @@
-/*************************************************************************/
-/*  thread_safe.cpp                                                      */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "thread_safe.h"
-
-#include "core/error_macros.h"
-#include "core/os/memory.h"
-
-ThreadSafe::ThreadSafe() {
-
-	mutex = Mutex::create();
-	if (!mutex) {
-
-		WARN_PRINT("THREAD_SAFE defined, but no default mutex type");
-	}
-}
-
-ThreadSafe::~ThreadSafe() {
-
-	if (mutex)
-		memdelete(mutex);
-}

+ 4 - 45
core/os/thread_safe.h

@@ -33,50 +33,9 @@
 
 #include "core/os/mutex.h"
 
-class ThreadSafe {
-
-	Mutex *mutex;
-
-public:
-	inline void lock() const {
-		if (mutex) mutex->lock();
-	}
-	inline void unlock() const {
-		if (mutex) mutex->unlock();
-	}
-
-	ThreadSafe();
-	~ThreadSafe();
-};
-
-class ThreadSafeMethod {
-
-	const ThreadSafe *_ts;
-
-public:
-	ThreadSafeMethod(const ThreadSafe *p_ts) {
-
-		_ts = p_ts;
-		_ts->lock();
-	}
-
-	~ThreadSafeMethod() { _ts->unlock(); }
-};
-
-#ifndef NO_THREADS
-
-#define _THREAD_SAFE_CLASS_ ThreadSafe __thread__safe__;
-#define _THREAD_SAFE_METHOD_ ThreadSafeMethod __thread_safe_method__(&__thread__safe__);
-#define _THREAD_SAFE_LOCK_ __thread__safe__.lock();
-#define _THREAD_SAFE_UNLOCK_ __thread__safe__.unlock();
-
-#else
-
-#define _THREAD_SAFE_CLASS_
-#define _THREAD_SAFE_METHOD_
-#define _THREAD_SAFE_LOCK_
-#define _THREAD_SAFE_UNLOCK_
-
-#endif
+#define _THREAD_SAFE_CLASS_ mutable Mutex _thread_safe_;
+#define _THREAD_SAFE_METHOD_ MutexLock _thread_safe_method_(_thread_safe_);
+#define _THREAD_SAFE_LOCK_ _thread_safe_.lock();
+#define _THREAD_SAFE_UNLOCK_ _thread_safe_.unlock();
 
 #endif

+ 2 - 5
core/pool_vector.cpp

@@ -30,7 +30,7 @@
 
 #include "pool_vector.h"
 
-Mutex *pool_vector_lock = NULL;
+Mutex pool_vector_lock;
 
 PoolAllocator *MemoryPool::memory_pool = NULL;
 uint8_t *MemoryPool::pool_memory = NULL;
@@ -40,7 +40,7 @@ MemoryPool::Alloc *MemoryPool::allocs = NULL;
 MemoryPool::Alloc *MemoryPool::free_list = NULL;
 uint32_t MemoryPool::alloc_count = 0;
 uint32_t MemoryPool::allocs_used = 0;
-Mutex *MemoryPool::alloc_mutex = NULL;
+Mutex MemoryPool::alloc_mutex;
 
 size_t MemoryPool::total_memory = 0;
 size_t MemoryPool::max_memory = 0;
@@ -57,14 +57,11 @@ void MemoryPool::setup(uint32_t p_max_allocs) {
 	}
 
 	free_list = &allocs[0];
-
-	alloc_mutex = Mutex::create();
 }
 
 void MemoryPool::cleanup() {
 
 	memdelete_arr(allocs);
-	memdelete(alloc_mutex);
 
 	ERR_FAIL_COND_MSG(allocs_used > 0, "There are still MemoryPool allocs in use at exit!");
 }

+ 19 - 19
core/pool_vector.h

@@ -69,7 +69,7 @@ struct MemoryPool {
 	static Alloc *free_list;
 	static uint32_t alloc_count;
 	static uint32_t allocs_used;
-	static Mutex *alloc_mutex;
+	static Mutex alloc_mutex;
 	static size_t total_memory;
 	static size_t max_memory;
 
@@ -95,9 +95,9 @@ class PoolVector {
 
 		//must allocate something
 
-		MemoryPool::alloc_mutex->lock();
+		MemoryPool::alloc_mutex.lock();
 		if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
-			MemoryPool::alloc_mutex->unlock();
+			MemoryPool::alloc_mutex.unlock();
 			ERR_FAIL_MSG("All memory pool allocations are in use, can't COW.");
 		}
 
@@ -122,7 +122,7 @@ class PoolVector {
 		}
 #endif
 
-		MemoryPool::alloc_mutex->unlock();
+		MemoryPool::alloc_mutex.unlock();
 
 		if (MemoryPool::memory_pool) {
 
@@ -148,9 +148,9 @@ class PoolVector {
 			//this should never happen but..
 
 #ifdef DEBUG_ENABLED
-			MemoryPool::alloc_mutex->lock();
+			MemoryPool::alloc_mutex.lock();
 			MemoryPool::total_memory -= old_alloc->size;
-			MemoryPool::alloc_mutex->unlock();
+			MemoryPool::alloc_mutex.unlock();
 #endif
 
 			{
@@ -174,11 +174,11 @@ class PoolVector {
 				old_alloc->mem = NULL;
 				old_alloc->size = 0;
 
-				MemoryPool::alloc_mutex->lock();
+				MemoryPool::alloc_mutex.lock();
 				old_alloc->free_list = MemoryPool::free_list;
 				MemoryPool::free_list = old_alloc;
 				MemoryPool::allocs_used--;
-				MemoryPool::alloc_mutex->unlock();
+				MemoryPool::alloc_mutex.unlock();
 			}
 		}
 	}
@@ -227,9 +227,9 @@ class PoolVector {
 		}
 
 #ifdef DEBUG_ENABLED
-		MemoryPool::alloc_mutex->lock();
+		MemoryPool::alloc_mutex.lock();
 		MemoryPool::total_memory -= alloc->size;
-		MemoryPool::alloc_mutex->unlock();
+		MemoryPool::alloc_mutex.unlock();
 #endif
 
 		if (MemoryPool::memory_pool) {
@@ -242,11 +242,11 @@ class PoolVector {
 			alloc->mem = NULL;
 			alloc->size = 0;
 
-			MemoryPool::alloc_mutex->lock();
+			MemoryPool::alloc_mutex.lock();
 			alloc->free_list = MemoryPool::free_list;
 			MemoryPool::free_list = alloc;
 			MemoryPool::allocs_used--;
-			MemoryPool::alloc_mutex->unlock();
+			MemoryPool::alloc_mutex.unlock();
 		}
 
 		alloc = NULL;
@@ -523,9 +523,9 @@ Error PoolVector<T>::resize(int p_size) {
 			return OK; //nothing to do here
 
 		//must allocate something
-		MemoryPool::alloc_mutex->lock();
+		MemoryPool::alloc_mutex.lock();
 		if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
-			MemoryPool::alloc_mutex->unlock();
+			MemoryPool::alloc_mutex.unlock();
 			ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "All memory pool allocations are in use.");
 		}
 
@@ -539,7 +539,7 @@ Error PoolVector<T>::resize(int p_size) {
 		alloc->size = 0;
 		alloc->refcount.init();
 		alloc->pool_id = POOL_ALLOCATOR_INVALID_ID;
-		MemoryPool::alloc_mutex->unlock();
+		MemoryPool::alloc_mutex.unlock();
 
 	} else {
 
@@ -559,13 +559,13 @@ Error PoolVector<T>::resize(int p_size) {
 	_copy_on_write(); // make it unique
 
 #ifdef DEBUG_ENABLED
-	MemoryPool::alloc_mutex->lock();
+	MemoryPool::alloc_mutex.lock();
 	MemoryPool::total_memory -= alloc->size;
 	MemoryPool::total_memory += new_size;
 	if (MemoryPool::total_memory > MemoryPool::max_memory) {
 		MemoryPool::max_memory = MemoryPool::total_memory;
 	}
-	MemoryPool::alloc_mutex->unlock();
+	MemoryPool::alloc_mutex.unlock();
 #endif
 
 	int cur_elements = alloc->size / sizeof(T);
@@ -615,11 +615,11 @@ Error PoolVector<T>::resize(int p_size) {
 				alloc->mem = NULL;
 				alloc->size = 0;
 
-				MemoryPool::alloc_mutex->lock();
+				MemoryPool::alloc_mutex.lock();
 				alloc->free_list = MemoryPool::free_list;
 				MemoryPool::free_list = alloc;
 				MemoryPool::allocs_used--;
-				MemoryPool::alloc_mutex->unlock();
+				MemoryPool::alloc_mutex.unlock();
 
 			} else {
 				alloc->mem = memrealloc(alloc->mem, new_size);

+ 1 - 9
core/register_core_types.cpp

@@ -90,7 +90,7 @@ static IP *ip = NULL;
 
 static _Geometry *_geometry = NULL;
 
-extern Mutex *_global_mutex;
+extern Mutex _global_mutex;
 
 extern void register_global_constants();
 extern void unregister_global_constants();
@@ -101,10 +101,7 @@ void register_core_types() {
 
 	MemoryPool::setup();
 
-	_global_mutex = Mutex::create();
-
 	StringName::setup();
-	ResourceLoader::initialize();
 
 	register_global_constants();
 	register_variant_methods();
@@ -316,10 +313,5 @@ void unregister_core_types() {
 	CoreStringNames::free();
 	StringName::cleanup();
 
-	if (_global_mutex) {
-		memdelete(_global_mutex);
-		_global_mutex = NULL; //still needed at a few places
-	};
-
 	MemoryPool::cleanup();
 }

+ 23 - 27
core/string_name.cpp

@@ -47,12 +47,10 @@ StringName _scs_create(const char *p_chr) {
 }
 
 bool StringName::configured = false;
-Mutex *StringName::lock = NULL;
+Mutex StringName::lock;
 
 void StringName::setup() {
 
-	lock = Mutex::create();
-
 	ERR_FAIL_COND(configured);
 	for (int i = 0; i < STRING_TABLE_LEN; i++) {
 
@@ -63,7 +61,7 @@ void StringName::setup() {
 
 void StringName::cleanup() {
 
-	lock->lock();
+	lock.lock();
 
 	int lost_strings = 0;
 	for (int i = 0; i < STRING_TABLE_LEN; i++) {
@@ -87,9 +85,7 @@ void StringName::cleanup() {
 	if (lost_strings) {
 		print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit.");
 	}
-	lock->unlock();
-
-	memdelete(lock);
+	lock.unlock();
 }
 
 void StringName::unref() {
@@ -98,7 +94,7 @@ void StringName::unref() {
 
 	if (_data && _data->refcount.unref()) {
 
-		lock->lock();
+		lock.lock();
 
 		if (_data->prev) {
 			_data->prev->next = _data->next;
@@ -113,7 +109,7 @@ void StringName::unref() {
 			_data->next->prev = _data->prev;
 		}
 		memdelete(_data);
-		lock->unlock();
+		lock.unlock();
 	}
 
 	_data = NULL;
@@ -184,7 +180,7 @@ StringName::StringName(const char *p_name) {
 	if (!p_name || p_name[0] == 0)
 		return; //empty, ignore
 
-	lock->lock();
+	lock.lock();
 
 	uint32_t hash = String::hash(p_name);
 
@@ -203,7 +199,7 @@ StringName::StringName(const char *p_name) {
 	if (_data) {
 		if (_data->refcount.ref()) {
 			// exists
-			lock->unlock();
+			lock.unlock();
 			return;
 		}
 	}
@@ -220,7 +216,7 @@ StringName::StringName(const char *p_name) {
 		_table[idx]->prev = _data;
 	_table[idx] = _data;
 
-	lock->unlock();
+	lock.unlock();
 }
 
 StringName::StringName(const StaticCString &p_static_string) {
@@ -231,7 +227,7 @@ StringName::StringName(const StaticCString &p_static_string) {
 
 	ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]);
 
-	lock->lock();
+	lock.lock();
 
 	uint32_t hash = String::hash(p_static_string.ptr);
 
@@ -250,7 +246,7 @@ StringName::StringName(const StaticCString &p_static_string) {
 	if (_data) {
 		if (_data->refcount.ref()) {
 			// exists
-			lock->unlock();
+			lock.unlock();
 			return;
 		}
 	}
@@ -267,7 +263,7 @@ StringName::StringName(const StaticCString &p_static_string) {
 		_table[idx]->prev = _data;
 	_table[idx] = _data;
 
-	lock->unlock();
+	lock.unlock();
 }
 
 StringName::StringName(const String &p_name) {
@@ -279,7 +275,7 @@ StringName::StringName(const String &p_name) {
 	if (p_name == String())
 		return;
 
-	lock->lock();
+	lock.lock();
 
 	uint32_t hash = p_name.hash();
 
@@ -297,7 +293,7 @@ StringName::StringName(const String &p_name) {
 	if (_data) {
 		if (_data->refcount.ref()) {
 			// exists
-			lock->unlock();
+			lock.unlock();
 			return;
 		}
 	}
@@ -314,7 +310,7 @@ StringName::StringName(const String &p_name) {
 		_table[idx]->prev = _data;
 	_table[idx] = _data;
 
-	lock->unlock();
+	lock.unlock();
 }
 
 StringName StringName::search(const char *p_name) {
@@ -325,7 +321,7 @@ StringName StringName::search(const char *p_name) {
 	if (!p_name[0])
 		return StringName();
 
-	lock->lock();
+	lock.lock();
 
 	uint32_t hash = String::hash(p_name);
 
@@ -342,12 +338,12 @@ StringName StringName::search(const char *p_name) {
 	}
 
 	if (_data && _data->refcount.ref()) {
-		lock->unlock();
+		lock.unlock();
 
 		return StringName(_data);
 	}
 
-	lock->unlock();
+	lock.unlock();
 	return StringName(); //does not exist
 }
 
@@ -359,7 +355,7 @@ StringName StringName::search(const CharType *p_name) {
 	if (!p_name[0])
 		return StringName();
 
-	lock->lock();
+	lock.lock();
 
 	uint32_t hash = String::hash(p_name);
 
@@ -376,18 +372,18 @@ StringName StringName::search(const CharType *p_name) {
 	}
 
 	if (_data && _data->refcount.ref()) {
-		lock->unlock();
+		lock.unlock();
 		return StringName(_data);
 	}
 
-	lock->unlock();
+	lock.unlock();
 	return StringName(); //does not exist
 }
 StringName StringName::search(const String &p_name) {
 
 	ERR_FAIL_COND_V(p_name == "", StringName());
 
-	lock->lock();
+	lock.lock();
 
 	uint32_t hash = p_name.hash();
 
@@ -404,11 +400,11 @@ StringName StringName::search(const String &p_name) {
 	}
 
 	if (_data && _data->refcount.ref()) {
-		lock->unlock();
+		lock.unlock();
 		return StringName(_data);
 	}
 
-	lock->unlock();
+	lock.unlock();
 	return StringName(); //does not exist
 }
 

+ 1 - 1
core/string_name.h

@@ -82,7 +82,7 @@ class StringName {
 	friend void register_core_types();
 	friend void unregister_core_types();
 
-	static Mutex *lock;
+	static Mutex lock;
 	static void setup();
 	static void cleanup();
 	static bool configured;

+ 4 - 11
drivers/alsa/audio_driver_alsa.cpp

@@ -169,7 +169,6 @@ Error AudioDriverALSA::init() {
 
 	Error err = init_device();
 	if (err == OK) {
-		mutex = Mutex::create();
 		thread = Thread::create(AudioDriverALSA::thread_func, this);
 	}
 
@@ -314,16 +313,16 @@ void AudioDriverALSA::set_device(String device) {
 
 void AudioDriverALSA::lock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->lock();
+	mutex.lock();
 }
 
 void AudioDriverALSA::unlock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void AudioDriverALSA::finish_device() {
@@ -342,11 +341,6 @@ void AudioDriverALSA::finish() {
 
 		memdelete(thread);
 		thread = NULL;
-
-		if (mutex) {
-			memdelete(mutex);
-			mutex = NULL;
-		}
 	}
 
 	finish_device();
@@ -354,7 +348,6 @@ void AudioDriverALSA::finish() {
 
 AudioDriverALSA::AudioDriverALSA() :
 		thread(NULL),
-		mutex(NULL),
 		pcm_handle(NULL),
 		device_name("Default"),
 		new_device("Default") {

+ 1 - 1
drivers/alsa/audio_driver_alsa.h

@@ -42,7 +42,7 @@
 class AudioDriverALSA : public AudioDriver {
 
 	Thread *thread;
-	Mutex *mutex;
+	Mutex mutex;
 
 	snd_pcm_t *pcm_handle;
 

+ 2 - 11
drivers/alsamidi/midi_driver_alsamidi.cpp

@@ -148,7 +148,6 @@ Error MIDIDriverALSAMidi::open() {
 	}
 	snd_device_name_free_hint(hints);
 
-	mutex = Mutex::create();
 	exit_thread = false;
 	thread = Thread::create(MIDIDriverALSAMidi::thread_func, this);
 
@@ -165,11 +164,6 @@ void MIDIDriverALSAMidi::close() {
 		thread = NULL;
 	}
 
-	if (mutex) {
-		memdelete(mutex);
-		mutex = NULL;
-	}
-
 	for (int i = 0; i < connected_inputs.size(); i++) {
 		snd_rawmidi_t *midi_in = connected_inputs[i];
 		snd_rawmidi_close(midi_in);
@@ -179,14 +173,12 @@ void MIDIDriverALSAMidi::close() {
 
 void MIDIDriverALSAMidi::lock() const {
 
-	if (mutex)
-		mutex->lock();
+	mutex.lock();
 }
 
 void MIDIDriverALSAMidi::unlock() const {
 
-	if (mutex)
-		mutex->unlock();
+	mutex.unlock();
 }
 
 PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() {
@@ -210,7 +202,6 @@ PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() {
 
 MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
 
-	mutex = NULL;
 	thread = NULL;
 
 	exit_thread = false;

+ 1 - 1
drivers/alsamidi/midi_driver_alsamidi.h

@@ -44,7 +44,7 @@
 class MIDIDriverALSAMidi : public MIDIDriver {
 
 	Thread *thread;
-	Mutex *mutex;
+	Mutex mutex;
 
 	Vector<snd_rawmidi_t *> connected_inputs;
 

+ 3 - 15
drivers/coreaudio/audio_driver_coreaudio.cpp

@@ -69,8 +69,6 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
 #endif
 
 Error AudioDriverCoreAudio::init() {
-	mutex = Mutex::create();
-
 	AudioComponentDescription desc;
 	zeromem(&desc, sizeof(desc));
 	desc.componentType = kAudioUnitType_Output;
@@ -280,19 +278,15 @@ AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const {
 };
 
 void AudioDriverCoreAudio::lock() {
-	if (mutex)
-		mutex->lock();
+	mutex.lock();
 };
 
 void AudioDriverCoreAudio::unlock() {
-	if (mutex)
-		mutex->unlock();
+	mutex.unlock();
 };
 
 bool AudioDriverCoreAudio::try_lock() {
-	if (mutex)
-		return mutex->try_lock() == OK;
-	return true;
+	return mutex.try_lock() == OK;
 }
 
 void AudioDriverCoreAudio::finish() {
@@ -344,11 +338,6 @@ void AudioDriverCoreAudio::finish() {
 		audio_unit = NULL;
 		unlock();
 	}
-
-	if (mutex) {
-		memdelete(mutex);
-		mutex = NULL;
-	}
 }
 
 Error AudioDriverCoreAudio::capture_init() {
@@ -691,7 +680,6 @@ AudioDriverCoreAudio::AudioDriverCoreAudio() :
 		audio_unit(NULL),
 		input_unit(NULL),
 		active(false),
-		mutex(NULL),
 		device_name("Default"),
 		capture_device_name("Default"),
 		mix_rate(0),

+ 1 - 1
drivers/coreaudio/audio_driver_coreaudio.h

@@ -46,7 +46,7 @@ class AudioDriverCoreAudio : public AudioDriver {
 	AudioComponentInstance input_unit;
 
 	bool active;
-	Mutex *mutex;
+	Mutex mutex;
 
 	String device_name;
 	String capture_device_name;

+ 4 - 10
drivers/pulseaudio/audio_driver_pulseaudio.cpp

@@ -294,7 +294,6 @@ Error AudioDriverPulseAudio::init() {
 
 	Error err = init_device();
 	if (err == OK) {
-		mutex = Mutex::create();
 		thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
 	}
 
@@ -600,16 +599,16 @@ void AudioDriverPulseAudio::set_device(String device) {
 
 void AudioDriverPulseAudio::lock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->lock();
+	mutex.lock();
 }
 
 void AudioDriverPulseAudio::unlock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void AudioDriverPulseAudio::finish_device() {
@@ -643,10 +642,6 @@ void AudioDriverPulseAudio::finish() {
 	}
 
 	memdelete(thread);
-	if (mutex) {
-		memdelete(mutex);
-		mutex = NULL;
-	}
 
 	thread = NULL;
 }
@@ -803,7 +798,6 @@ String AudioDriverPulseAudio::capture_get_device() {
 
 AudioDriverPulseAudio::AudioDriverPulseAudio() :
 		thread(NULL),
-		mutex(NULL),
 		pa_ml(NULL),
 		pa_ctx(NULL),
 		pa_str(NULL),

+ 1 - 1
drivers/pulseaudio/audio_driver_pulseaudio.h

@@ -42,7 +42,7 @@
 class AudioDriverPulseAudio : public AudioDriver {
 
 	Thread *thread;
-	Mutex *mutex;
+	Mutex mutex;
 
 	pa_mainloop *pa_ml;
 	pa_context *pa_ctx;

+ 0 - 73
drivers/unix/mutex_posix.cpp

@@ -1,73 +0,0 @@
-/*************************************************************************/
-/*  mutex_posix.cpp                                                      */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "mutex_posix.h"
-
-#include "core/os/memory.h"
-
-#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
-
-void MutexPosix::lock() {
-
-	pthread_mutex_lock(&mutex);
-}
-void MutexPosix::unlock() {
-
-	pthread_mutex_unlock(&mutex);
-}
-Error MutexPosix::try_lock() {
-
-	return (pthread_mutex_trylock(&mutex) == 0) ? OK : ERR_BUSY;
-}
-
-Mutex *MutexPosix::create_func_posix(bool p_recursive) {
-
-	return memnew(MutexPosix(p_recursive));
-}
-
-void MutexPosix::make_default() {
-
-	create_func = create_func_posix;
-}
-
-MutexPosix::MutexPosix(bool p_recursive) {
-
-	pthread_mutexattr_init(&attr);
-	if (p_recursive)
-		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-	pthread_mutex_init(&mutex, &attr);
-}
-
-MutexPosix::~MutexPosix() {
-
-	pthread_mutex_destroy(&mutex);
-}
-
-#endif

+ 0 - 61
drivers/unix/mutex_posix.h

@@ -1,61 +0,0 @@
-/*************************************************************************/
-/*  mutex_posix.h                                                        */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef MUTEX_POSIX_H
-#define MUTEX_POSIX_H
-
-#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
-
-#include "core/os/mutex.h"
-
-#include <pthread.h>
-
-class MutexPosix : public Mutex {
-
-	pthread_mutexattr_t attr;
-	pthread_mutex_t mutex;
-
-	static Mutex *create_func_posix(bool p_recursive);
-
-public:
-	virtual void lock();
-	virtual void unlock();
-	virtual Error try_lock();
-
-	static void make_default();
-
-	MutexPosix(bool p_recursive);
-
-	~MutexPosix();
-};
-
-#endif
-
-#endif

+ 3 - 9
drivers/unix/os_unix.cpp

@@ -36,7 +36,6 @@
 #include "core/project_settings.h"
 #include "drivers/unix/dir_access_unix.h"
 #include "drivers/unix/file_access_unix.h"
-#include "drivers/unix/mutex_posix.h"
 #include "drivers/unix/net_socket_posix.h"
 #include "drivers/unix/semaphore_posix.h"
 #include "drivers/unix/thread_posix.h"
@@ -63,6 +62,7 @@
 #include <string.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <time.h>
 #include <unistd.h>
 
 /// Clock Setup function (used by get_ticks_usec)
@@ -122,13 +122,11 @@ void OS_Unix::initialize_core() {
 #ifdef NO_THREADS
 	ThreadDummy::make_default();
 	SemaphoreDummy::make_default();
-	MutexDummy::make_default();
 #else
 	ThreadPosix::make_default();
 #if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED)
 	SemaphorePosix::make_default();
 #endif
-	MutexPosix::make_default();
 #endif
 	FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
 	FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
@@ -307,13 +305,9 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
 
 		while (fgets(buf, 65535, f)) {
 
-			if (p_pipe_mutex) {
-				p_pipe_mutex->lock();
-			}
+			p_pipe_mutex->lock();
 			(*r_pipe) += String::utf8(buf);
-			if (p_pipe_mutex) {
-				p_pipe_mutex->unlock();
-			}
+			p_pipe_mutex->unlock();
 		}
 		int rv = pclose(f);
 		if (r_exitcode)

+ 2 - 11
drivers/wasapi/audio_driver_wasapi.cpp

@@ -406,7 +406,6 @@ Error AudioDriverWASAPI::init() {
 	exit_thread = false;
 	thread_exited = false;
 
-	mutex = Mutex::create(true);
 	thread = Thread::create(thread_func, this);
 
 	return OK;
@@ -782,14 +781,12 @@ void AudioDriverWASAPI::start() {
 
 void AudioDriverWASAPI::lock() {
 
-	if (mutex)
-		mutex->lock();
+	mutex.lock();
 }
 
 void AudioDriverWASAPI::unlock() {
 
-	if (mutex)
-		mutex->unlock();
+	mutex.unlock();
 }
 
 void AudioDriverWASAPI::finish() {
@@ -804,11 +801,6 @@ void AudioDriverWASAPI::finish() {
 
 	finish_capture_device();
 	finish_render_device();
-
-	if (mutex) {
-		memdelete(mutex);
-		mutex = NULL;
-	}
 }
 
 Error AudioDriverWASAPI::capture_start() {
@@ -863,7 +855,6 @@ String AudioDriverWASAPI::capture_get_device() {
 
 AudioDriverWASAPI::AudioDriverWASAPI() {
 
-	mutex = NULL;
 	thread = NULL;
 
 	samples_in.clear();

+ 1 - 1
drivers/wasapi/audio_driver_wasapi.h

@@ -75,7 +75,7 @@ class AudioDriverWASAPI : public AudioDriver {
 	AudioDeviceWASAPI audio_input;
 	AudioDeviceWASAPI audio_output;
 
-	Mutex *mutex;
+	Mutex mutex;
 	Thread *thread;
 
 	Vector<int32_t> samples_in;

+ 0 - 101
drivers/windows/mutex_windows.cpp

@@ -1,101 +0,0 @@
-/*************************************************************************/
-/*  mutex_windows.cpp                                                    */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "mutex_windows.h"
-
-#include "core/os/memory.h"
-
-#ifdef WINDOWS_ENABLED
-
-void MutexWindows::lock() {
-
-#ifdef WINDOWS_USE_MUTEX
-	WaitForSingleObject(mutex, INFINITE);
-#else
-	EnterCriticalSection(&mutex);
-#endif
-}
-
-void MutexWindows::unlock() {
-
-#ifdef WINDOWS_USE_MUTEX
-	ReleaseMutex(mutex);
-#else
-	LeaveCriticalSection(&mutex);
-#endif
-}
-
-Error MutexWindows::try_lock() {
-
-#ifdef WINDOWS_USE_MUTEX
-	return (WaitForSingleObject(mutex, 0) == WAIT_TIMEOUT) ? ERR_BUSY : OK;
-#else
-
-	if (TryEnterCriticalSection(&mutex))
-		return OK;
-	else
-		return ERR_BUSY;
-#endif
-}
-
-Mutex *MutexWindows::create_func_windows(bool p_recursive) {
-
-	return memnew(MutexWindows);
-}
-
-void MutexWindows::make_default() {
-
-	create_func = create_func_windows;
-}
-
-MutexWindows::MutexWindows() {
-
-#ifdef WINDOWS_USE_MUTEX
-	mutex = CreateMutex(NULL, FALSE, NULL);
-#else
-#ifdef UWP_ENABLED
-	InitializeCriticalSectionEx(&mutex, 0, 0);
-#else
-	InitializeCriticalSection(&mutex);
-#endif
-#endif
-}
-
-MutexWindows::~MutexWindows() {
-
-#ifdef WINDOWS_USE_MUTEX
-	CloseHandle(mutex);
-#else
-
-	DeleteCriticalSection(&mutex);
-#endif
-}
-
-#endif

+ 0 - 63
drivers/windows/mutex_windows.h

@@ -1,63 +0,0 @@
-/*************************************************************************/
-/*  mutex_windows.h                                                      */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef MUTEX_WINDOWS_H
-#define MUTEX_WINDOWS_H
-
-#ifdef WINDOWS_ENABLED
-
-#include "core/os/mutex.h"
-
-#include <windows.h>
-
-class MutexWindows : public Mutex {
-
-#ifdef WINDOWS_USE_MUTEX
-	HANDLE mutex;
-#else
-	CRITICAL_SECTION mutex;
-#endif
-
-	static Mutex *create_func_windows(bool p_recursive);
-
-public:
-	virtual void lock();
-	virtual void unlock();
-	virtual Error try_lock();
-
-	static void make_default();
-
-	MutexWindows();
-	~MutexWindows();
-};
-
-#endif
-
-#endif

+ 4 - 8
drivers/xaudio2/audio_driver_xaudio2.cpp

@@ -79,7 +79,6 @@ Error AudioDriverXAudio2::init() {
 	hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback);
 	ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 source voice. Error code: " + itos(hr) + ".");
 
-	mutex = Mutex::create();
 	thread = Thread::create(AudioDriverXAudio2::thread_func, this);
 
 	return OK;
@@ -158,15 +157,15 @@ float AudioDriverXAudio2::get_latency() {
 
 void AudioDriverXAudio2::lock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->lock();
+	mutex.lock();
 }
 void AudioDriverXAudio2::unlock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void AudioDriverXAudio2::finish() {
@@ -194,14 +193,11 @@ void AudioDriverXAudio2::finish() {
 	mastering_voice->DestroyVoice();
 
 	memdelete(thread);
-	if (mutex)
-		memdelete(mutex);
 	thread = NULL;
 }
 
 AudioDriverXAudio2::AudioDriverXAudio2() :
 		thread(NULL),
-		mutex(NULL),
 		current_buffer(0) {
 	wave_format = { 0 };
 	for (int i = 0; i < AUDIO_BUFFERS; i++) {

+ 1 - 1
drivers/xaudio2/audio_driver_xaudio2.h

@@ -65,7 +65,7 @@ class AudioDriverXAudio2 : public AudioDriver {
 	};
 
 	Thread *thread;
-	Mutex *mutex;
+	Mutex mutex;
 
 	int32_t *samples_in;
 	int16_t *samples_out[AUDIO_BUFFERS];

+ 3 - 5
editor/editor_node.cpp

@@ -5736,7 +5736,7 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err
 static void _execute_thread(void *p_ud) {
 
 	EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)p_ud;
-	Error err = OS::get_singleton()->execute(eta->path, eta->args, true, NULL, &eta->output, &eta->exitcode, true, eta->execute_output_mutex);
+	Error err = OS::get_singleton()->execute(eta->path, eta->args, true, NULL, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex);
 	print_verbose("Thread exit status: " + itos(eta->exitcode));
 	if (err != OK) {
 		eta->exitcode = err;
@@ -5756,7 +5756,6 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
 	ExecuteThreadArgs eta;
 	eta.path = p_path;
 	eta.args = p_arguments;
-	eta.execute_output_mutex = Mutex::create();
 	eta.exitcode = 255;
 	eta.done = false;
 
@@ -5767,20 +5766,19 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
 	ERR_FAIL_COND_V(!eta.execute_output_thread, 0);
 
 	while (!eta.done) {
-		eta.execute_output_mutex->lock();
+		eta.execute_output_mutex.lock();
 		if (prev_len != eta.output.length()) {
 			String to_add = eta.output.substr(prev_len, eta.output.length());
 			prev_len = eta.output.length();
 			execute_outputs->add_text(to_add);
 			Main::iteration();
 		}
-		eta.execute_output_mutex->unlock();
+		eta.execute_output_mutex.unlock();
 		OS::get_singleton()->delay_usec(1000);
 	}
 
 	Thread::wait_to_finish(eta.execute_output_thread);
 	memdelete(eta.execute_output_thread);
-	memdelete(eta.execute_output_mutex);
 	execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode));
 
 	if (p_close_on_errors && eta.exitcode != 0) {

+ 1 - 1
editor/editor_node.h

@@ -107,7 +107,7 @@ public:
 		List<String> args;
 		String output;
 		Thread *execute_output_thread;
-		Mutex *execute_output_mutex;
+		Mutex execute_output_mutex;
 		int exitcode;
 		volatile bool done;
 	};

+ 14 - 16
editor/editor_resource_preview.cpp

@@ -109,7 +109,7 @@ void EditorResourcePreview::_thread_func(void *ud) {
 
 void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture> &p_texture, const Ref<Texture> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) {
 
-	preview_mutex->lock();
+	preview_mutex.lock();
 
 	String path = p_str;
 	uint32_t hash = 0;
@@ -131,7 +131,7 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur
 
 	cache[path] = item;
 
-	preview_mutex->unlock();
+	preview_mutex.unlock();
 
 	MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_small_texture, p_ud);
 }
@@ -221,7 +221,7 @@ void EditorResourcePreview::_thread() {
 	while (!exit) {
 
 		preview_sem->wait();
-		preview_mutex->lock();
+		preview_mutex.lock();
 
 		if (queue.size()) {
 
@@ -237,10 +237,10 @@ void EditorResourcePreview::_thread() {
 
 				_preview_ready(path, cache[item.path].preview, cache[item.path].small_preview, item.id, item.function, item.userdata);
 
-				preview_mutex->unlock();
+				preview_mutex.unlock();
 			} else {
 
-				preview_mutex->unlock();
+				preview_mutex.unlock();
 
 				Ref<ImageTexture> texture;
 				Ref<ImageTexture> small_texture;
@@ -347,7 +347,7 @@ void EditorResourcePreview::_thread() {
 			}
 
 		} else {
-			preview_mutex->unlock();
+			preview_mutex.unlock();
 		}
 	}
 	exited = true;
@@ -358,7 +358,7 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
 	ERR_FAIL_NULL(p_receiver);
 	ERR_FAIL_COND(!p_res.is_valid());
 
-	preview_mutex->lock();
+	preview_mutex.lock();
 
 	String path_id = "ID:" + itos(p_res->get_instance_id());
 
@@ -366,7 +366,7 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
 
 		cache[path_id].order = order++;
 		p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata);
-		preview_mutex->unlock();
+		preview_mutex.unlock();
 		return;
 	}
 
@@ -380,18 +380,18 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
 	item.userdata = p_userdata;
 
 	queue.push_back(item);
-	preview_mutex->unlock();
+	preview_mutex.unlock();
 	preview_sem->post();
 }
 
 void EditorResourcePreview::queue_resource_preview(const String &p_path, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) {
 
 	ERR_FAIL_NULL(p_receiver);
-	preview_mutex->lock();
+	preview_mutex.lock();
 	if (cache.has(p_path)) {
 		cache[p_path].order = order++;
 		p_receiver->call(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata);
-		preview_mutex->unlock();
+		preview_mutex.unlock();
 		return;
 	}
 
@@ -402,7 +402,7 @@ void EditorResourcePreview::queue_resource_preview(const String &p_path, Object
 	item.userdata = p_userdata;
 
 	queue.push_back(item);
-	preview_mutex->unlock();
+	preview_mutex.unlock();
 	preview_sem->post();
 }
 
@@ -436,7 +436,7 @@ void EditorResourcePreview::_bind_methods() {
 
 void EditorResourcePreview::check_for_invalidation(const String &p_path) {
 
-	preview_mutex->lock();
+	preview_mutex.lock();
 
 	bool call_invalidated = false;
 	if (cache.has(p_path)) {
@@ -448,7 +448,7 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) {
 		}
 	}
 
-	preview_mutex->unlock();
+	preview_mutex.unlock();
 
 	if (call_invalidated) { //do outside mutex
 		call_deferred("emit_signal", "preview_invalidated", p_path);
@@ -477,7 +477,6 @@ void EditorResourcePreview::stop() {
 EditorResourcePreview::EditorResourcePreview() {
 	thread = NULL;
 	singleton = this;
-	preview_mutex = Mutex::create();
 	preview_sem = Semaphore::create();
 	order = 0;
 	exit = false;
@@ -487,6 +486,5 @@ EditorResourcePreview::EditorResourcePreview() {
 EditorResourcePreview::~EditorResourcePreview() {
 
 	stop();
-	memdelete(preview_mutex);
 	memdelete(preview_sem);
 }

+ 1 - 1
editor/editor_resource_preview.h

@@ -70,7 +70,7 @@ class EditorResourcePreview : public Node {
 
 	List<QueueItem> queue;
 
-	Mutex *preview_mutex;
+	Mutex preview_mutex;
 	Semaphore *preview_sem;
 	Thread *thread;
 	volatile bool exit;

+ 6 - 8
editor/fileserver/editor_file_server.cpp

@@ -42,9 +42,9 @@
 void EditorFileServer::_close_client(ClientData *cd) {
 
 	cd->connection->disconnect_from_host();
-	cd->efs->wait_mutex->lock();
+	cd->efs->wait_mutex.lock();
 	cd->efs->to_wait.insert(cd->thread);
-	cd->efs->wait_mutex->unlock();
+	cd->efs->wait_mutex.unlock();
 	while (cd->files.size()) {
 		memdelete(cd->files.front()->get());
 		cd->files.erase(cd->files.front());
@@ -295,16 +295,16 @@ void EditorFileServer::_thread_start(void *s) {
 			}
 		}
 
-		self->wait_mutex->lock();
+		self->wait_mutex.lock();
 		while (self->to_wait.size()) {
 			Thread *w = self->to_wait.front()->get();
 			self->to_wait.erase(w);
-			self->wait_mutex->unlock();
+			self->wait_mutex.unlock();
 			Thread::wait_to_finish(w);
 			memdelete(w);
-			self->wait_mutex->lock();
+			self->wait_mutex.lock();
 		}
-		self->wait_mutex->unlock();
+		self->wait_mutex.unlock();
 
 		OS::get_singleton()->delay_usec(100000);
 	}
@@ -331,7 +331,6 @@ void EditorFileServer::stop() {
 EditorFileServer::EditorFileServer() {
 
 	server.instance();
-	wait_mutex = Mutex::create();
 	quit = false;
 	active = false;
 	cmd = CMD_NONE;
@@ -346,5 +345,4 @@ EditorFileServer::~EditorFileServer() {
 	quit = true;
 	Thread::wait_to_finish(thread);
 	memdelete(thread);
-	memdelete(wait_mutex);
 }

+ 1 - 1
editor/fileserver/editor_file_server.h

@@ -62,7 +62,7 @@ class EditorFileServer : public Object {
 	static void _close_client(ClientData *cd);
 	static void _subthread_start(void *s);
 
-	Mutex *wait_mutex;
+	Mutex wait_mutex;
 	Thread *thread;
 	static void _thread_start(void *);
 	bool quit;

+ 9 - 15
editor/import/resource_importer_texture.cpp

@@ -38,7 +38,7 @@
 
 void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) {
 
-	singleton->mutex->lock();
+	singleton->mutex.lock();
 	StringName path = p_tex->get_path();
 
 	if (!singleton->make_flags.has(path)) {
@@ -47,12 +47,12 @@ void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p
 
 	singleton->make_flags[path] |= MAKE_SRGB_FLAG;
 
-	singleton->mutex->unlock();
+	singleton->mutex.unlock();
 }
 
 void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) {
 
-	singleton->mutex->lock();
+	singleton->mutex.lock();
 	StringName path = p_tex->get_path();
 
 	if (!singleton->make_flags.has(path)) {
@@ -61,12 +61,12 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_t
 
 	singleton->make_flags[path] |= MAKE_3D_FLAG;
 
-	singleton->mutex->unlock();
+	singleton->mutex.unlock();
 }
 
 void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) {
 
-	singleton->mutex->lock();
+	singleton->mutex.lock();
 	StringName path = p_tex->get_path();
 
 	if (!singleton->make_flags.has(path)) {
@@ -75,7 +75,7 @@ void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture>
 
 	singleton->make_flags[path] |= MAKE_NORMAL_FLAG;
 
-	singleton->mutex->unlock();
+	singleton->mutex.unlock();
 }
 
 void ResourceImporterTexture::update_imports() {
@@ -83,10 +83,10 @@ void ResourceImporterTexture::update_imports() {
 	if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) {
 		return; // do nothing for now
 	}
-	mutex->lock();
+	mutex.lock();
 
 	if (make_flags.empty()) {
-		mutex->unlock();
+		mutex.unlock();
 		return;
 	}
 
@@ -128,7 +128,7 @@ void ResourceImporterTexture::update_imports() {
 
 	make_flags.clear();
 
-	mutex->unlock();
+	mutex.unlock();
 
 	if (to_reimport.size()) {
 		EditorFileSystem::get_singleton()->reimport_files(to_reimport);
@@ -611,10 +611,4 @@ ResourceImporterTexture::ResourceImporterTexture() {
 	StreamTexture::request_3d_callback = _texture_reimport_3d;
 	StreamTexture::request_srgb_callback = _texture_reimport_srgb;
 	StreamTexture::request_normal_callback = _texture_reimport_normal;
-	mutex = Mutex::create();
-}
-
-ResourceImporterTexture::~ResourceImporterTexture() {
-
-	memdelete(mutex);
 }

+ 1 - 2
editor/import/resource_importer_texture.h

@@ -46,7 +46,7 @@ protected:
 		MAKE_NORMAL_FLAG = 4
 	};
 
-	Mutex *mutex;
+	Mutex mutex;
 	Map<StringName, int> make_flags;
 
 	static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex);
@@ -94,7 +94,6 @@ public:
 	virtual String get_import_settings_string() const;
 
 	ResourceImporterTexture();
-	~ResourceImporterTexture();
 };
 
 #endif // RESOURCEIMPORTTEXTURE_H

+ 4 - 28
modules/gdnative/nativescript/nativescript.cpp

@@ -220,15 +220,9 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) {
 	nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
 #endif
 
-#ifndef NO_THREADS
-	owners_lock->lock();
-#endif
-
+	owners_lock.lock();
 	instance_owners.insert(p_this);
-
-#ifndef NO_THREADS
-	owners_lock->unlock();
-#endif
+	owners_lock.unlock();
 
 	return nsi;
 }
@@ -524,17 +518,10 @@ NativeScript::NativeScript() {
 	library = Ref<GDNative>();
 	lib_path = "";
 	class_name = "";
-#ifndef NO_THREADS
-	owners_lock = Mutex::create();
-#endif
 }
 
 NativeScript::~NativeScript() {
 	NSL->unregister_script(this);
-
-#ifndef NO_THREADS
-	memdelete(owners_lock);
-#endif
 }
 
 #define GET_SCRIPT_DESC() script->get_script_desc()
@@ -911,15 +898,9 @@ NativeScriptInstance::~NativeScriptInstance() {
 
 	if (owner) {
 
-#ifndef NO_THREADS
-		script->owners_lock->lock();
-#endif
-
+		script->owners_lock.lock();
 		script->instance_owners.erase(owner);
-
-#ifndef NO_THREADS
-		script->owners_lock->unlock();
-#endif
+		script->owners_lock.unlock();
 	}
 }
 
@@ -1016,7 +997,6 @@ NativeScriptLanguage::NativeScriptLanguage() {
 	NativeScriptLanguage::singleton = this;
 #ifndef NO_THREADS
 	has_objects_to_register = false;
-	mutex = Mutex::create();
 #endif
 
 #ifdef DEBUG_ENABLED
@@ -1053,10 +1033,6 @@ NativeScriptLanguage::~NativeScriptLanguage() {
 	NSL->library_classes.clear();
 	NSL->library_gdnatives.clear();
 	NSL->library_script_users.clear();
-
-#ifndef NO_THREADS
-	memdelete(mutex);
-#endif
 }
 
 String NativeScriptLanguage::get_name() const {

+ 2 - 4
modules/gdnative/nativescript/nativescript.h

@@ -121,9 +121,7 @@ class NativeScript : public Script {
 	String script_class_name;
 	String script_class_icon_path;
 
-#ifndef NO_THREADS
-	Mutex *owners_lock;
-#endif
+	Mutex owners_lock;
 	Set<Object *> instance_owners;
 
 protected:
@@ -238,7 +236,7 @@ private:
 	void _unload_stuff(bool p_reload = false);
 
 #ifndef NO_THREADS
-	Mutex *mutex;
+	Mutex mutex;
 
 	Set<Ref<GDNativeLibrary> > libs_to_init;
 	Set<NativeScript *> scripts_to_register;

+ 2 - 26
modules/gdnative/pluginscript/pluginscript_language.cpp

@@ -400,39 +400,15 @@ void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool
 }
 
 void PluginScriptLanguage::lock() {
-#ifndef NO_THREADS
-	if (_lock) {
-		_lock->lock();
-	}
-#endif
+	_lock.lock();
 }
 
 void PluginScriptLanguage::unlock() {
-#ifndef NO_THREADS
-	if (_lock) {
-		_lock->unlock();
-	}
-#endif
+	_lock.unlock();
 }
 
 PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) :
 		_desc(*desc) {
 	_resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this)));
 	_resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this)));
-
-// TODO: totally remove _lock attribute if NO_THREADS is set
-#ifdef NO_THREADS
-	_lock = NULL;
-#else
-	_lock = Mutex::create();
-#endif
-}
-
-PluginScriptLanguage::~PluginScriptLanguage() {
-#ifndef NO_THREADS
-	if (_lock) {
-		memdelete(_lock);
-		_lock = NULL;
-	}
-#endif
 }

+ 2 - 2
modules/gdnative/pluginscript/pluginscript_language.h

@@ -53,7 +53,7 @@ class PluginScriptLanguage : public ScriptLanguage {
 	const godot_pluginscript_language_desc _desc;
 	godot_pluginscript_language_data *_data;
 
-	Mutex *_lock;
+	Mutex _lock;
 	SelfList<PluginScript>::List _script_list;
 
 public:
@@ -126,7 +126,7 @@ public:
 	void unlock();
 
 	PluginScriptLanguage(const godot_pluginscript_language_desc *desc);
-	virtual ~PluginScriptLanguage();
+	virtual ~PluginScriptLanguage() {}
 };
 
 #endif // PLUGINSCRIPT_LANGUAGE_H

+ 30 - 106
modules/gdscript/gdscript.cpp

@@ -101,15 +101,9 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
 
 	/* STEP 2, INITIALIZE AND CONSTRUCT */
 
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->lock();
-#endif
-
+	GDScriptLanguage::singleton->lock.lock();
 	instances.insert(instance->owner);
-
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->unlock();
-#endif
+	GDScriptLanguage::singleton->lock.unlock();
 
 	initializer->call(instance, p_args, p_argcount, r_error);
 
@@ -117,11 +111,11 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
 		instance->script = Ref<GDScript>();
 		instance->owner->set_script_instance(NULL);
 #ifndef NO_THREADS
-		GDScriptLanguage::singleton->lock->lock();
+		GDScriptLanguage::singleton->lock.lock();
 #endif
 		instances.erase(p_owner);
 #ifndef NO_THREADS
-		GDScriptLanguage::singleton->lock->unlock();
+		GDScriptLanguage::singleton->lock.unlock();
 #endif
 
 		ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
@@ -343,14 +337,9 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
 
 bool GDScript::instance_has(const Object *p_this) const {
 
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->lock();
-#endif
+	GDScriptLanguage::singleton->lock.lock();
 	bool hasit = instances.has((Object *)p_this);
-
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->unlock();
-#endif
+	GDScriptLanguage::singleton->lock.unlock();
 
 	return hasit;
 }
@@ -564,14 +553,9 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
 
 Error GDScript::reload(bool p_keep_state) {
 
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->lock();
-#endif
+	GDScriptLanguage::singleton->lock.lock();
 	bool has_instances = instances.size();
-
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->unlock();
-#endif
+	GDScriptLanguage::singleton->lock.unlock();
 
 	ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
 
@@ -926,14 +910,9 @@ GDScript::GDScript() :
 #endif
 
 #ifdef DEBUG_ENABLED
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->lock();
-	}
+	GDScriptLanguage::get_singleton()->lock.lock();
 	GDScriptLanguage::get_singleton()->script_list.add(&script_list);
-
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->unlock();
-	}
+	GDScriptLanguage::get_singleton()->lock.unlock();
 #endif
 }
 
@@ -970,18 +949,14 @@ void GDScript::_save_orphaned_subclasses() {
 
 GDScript::~GDScript() {
 
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->lock();
-	}
+	GDScriptLanguage::get_singleton()->lock.lock();
 	while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
 		// Order matters since clearing the stack may already cause
 		// the GDSCriptFunctionState to be destroyed and thus removed from the list.
 		pending_func_states.remove(E);
 		E->self()->_clear_stack();
 	}
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->unlock();
-	}
+	GDScriptLanguage::get_singleton()->lock.unlock();
 
 	for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
 		memdelete(E->get());
@@ -990,14 +965,9 @@ GDScript::~GDScript() {
 	_save_orphaned_subclasses();
 
 #ifdef DEBUG_ENABLED
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->lock();
-	}
+	GDScriptLanguage::get_singleton()->lock.lock();
 	GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
-
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->unlock();
-	}
+	GDScriptLanguage::get_singleton()->lock.unlock();
 #endif
 }
 
@@ -1400,9 +1370,7 @@ GDScriptInstance::GDScriptInstance() {
 }
 
 GDScriptInstance::~GDScriptInstance() {
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->lock();
-#endif
+	GDScriptLanguage::singleton->lock.lock();
 
 	while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
 		// Order matters since clearing the stack may already cause
@@ -1415,9 +1383,7 @@ GDScriptInstance::~GDScriptInstance() {
 		script->instances.erase(owner);
 	}
 
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->unlock();
-#endif
+	GDScriptLanguage::singleton->lock.unlock();
 }
 
 /************* SCRIPT LANGUAGE **************/
@@ -1517,9 +1483,7 @@ void GDScriptLanguage::finish() {
 void GDScriptLanguage::profiling_start() {
 
 #ifdef DEBUG_ENABLED
-	if (lock) {
-		lock->lock();
-	}
+	lock.lock();
 
 	SelfList<GDScriptFunction> *elem = function_list.first();
 	while (elem) {
@@ -1536,25 +1500,16 @@ void GDScriptLanguage::profiling_start() {
 	}
 
 	profiling = true;
-	if (lock) {
-		lock->unlock();
-	}
-
+	lock.unlock();
 #endif
 }
 
 void GDScriptLanguage::profiling_stop() {
 
 #ifdef DEBUG_ENABLED
-	if (lock) {
-		lock->lock();
-	}
-
+	lock.lock();
 	profiling = false;
-	if (lock) {
-		lock->unlock();
-	}
-
+	lock.unlock();
 #endif
 }
 
@@ -1562,9 +1517,7 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
 
 	int current = 0;
 #ifdef DEBUG_ENABLED
-	if (lock) {
-		lock->lock();
-	}
+	lock.lock();
 
 	SelfList<GDScriptFunction> *elem = function_list.first();
 	while (elem) {
@@ -1578,10 +1531,7 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
 		current++;
 	}
 
-	if (lock) {
-		lock->unlock();
-	}
-
+	lock.unlock();
 #endif
 
 	return current;
@@ -1592,9 +1542,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
 	int current = 0;
 
 #ifdef DEBUG_ENABLED
-	if (lock) {
-		lock->lock();
-	}
+	lock.lock();
 
 	SelfList<GDScriptFunction> *elem = function_list.first();
 	while (elem) {
@@ -1610,10 +1558,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
 		elem = elem->next();
 	}
 
-	if (lock) {
-		lock->unlock();
-	}
-
+	lock.unlock();
 #endif
 
 	return current;
@@ -1644,9 +1589,7 @@ void GDScriptLanguage::reload_all_scripts() {
 
 #ifdef DEBUG_ENABLED
 	print_verbose("GDScript: Reloading all scripts");
-	if (lock) {
-		lock->lock();
-	}
+	lock.lock();
 
 	List<Ref<GDScript> > scripts;
 
@@ -1659,9 +1602,7 @@ void GDScriptLanguage::reload_all_scripts() {
 		elem = elem->next();
 	}
 
-	if (lock) {
-		lock->unlock();
-	}
+	lock.unlock();
 
 	//as scripts are going to be reloaded, must proceed without locking here
 
@@ -1680,9 +1621,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
 
 #ifdef DEBUG_ENABLED
 
-	if (lock) {
-		lock->lock();
-	}
+	lock.lock();
 
 	List<Ref<GDScript> > scripts;
 
@@ -1695,9 +1634,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
 		elem = elem->next();
 	}
 
-	if (lock) {
-		lock->unlock();
-	}
+	lock.unlock();
 
 	//when someone asks you why dynamically typed languages are easier to write....
 
@@ -1816,9 +1753,7 @@ void GDScriptLanguage::frame() {
 
 #ifdef DEBUG_ENABLED
 	if (profiling) {
-		if (lock) {
-			lock->lock();
-		}
+		lock.lock();
 
 		SelfList<GDScriptFunction> *elem = function_list.first();
 		while (elem) {
@@ -1831,9 +1766,7 @@ void GDScriptLanguage::frame() {
 			elem = elem->next();
 		}
 
-		if (lock) {
-			lock->unlock();
-		}
+		lock.unlock();
 	}
 
 #endif
@@ -2202,11 +2135,6 @@ GDScriptLanguage::GDScriptLanguage() {
 	_debug_parse_err_line = -1;
 	_debug_parse_err_file = "";
 
-#ifdef NO_THREADS
-	lock = NULL;
-#else
-	lock = Mutex::create();
-#endif
 	profiling = false;
 	script_frame_time = 0;
 
@@ -2240,10 +2168,6 @@ GDScriptLanguage::GDScriptLanguage() {
 
 GDScriptLanguage::~GDScriptLanguage() {
 
-	if (lock) {
-		memdelete(lock);
-		lock = NULL;
-	}
 	if (_call_stack) {
 		memdelete_arr(_call_stack);
 	}

+ 1 - 1
modules/gdscript/gdscript.h

@@ -351,7 +351,7 @@ class GDScriptLanguage : public ScriptLanguage {
 
 	friend class GDScriptInstance;
 
-	Mutex *lock;
+	Mutex lock;
 
 	friend class GDScript;
 

+ 8 - 26
modules/gdscript/gdscript_function.cpp

@@ -1279,9 +1279,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 				gdfs->state.ip = ip + ipofs;
 				gdfs->state.line = line;
 				gdfs->state.script = _script;
-#ifndef NO_THREADS
-				GDScriptLanguage::singleton->lock->lock();
-#endif
+				GDScriptLanguage::singleton->lock.lock();
 
 				_script->pending_func_states.add(&gdfs->scripts_list);
 				if (p_instance) {
@@ -1290,9 +1288,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 				} else {
 					gdfs->state.instance = NULL;
 				}
-#ifndef NO_THREADS
-				GDScriptLanguage::singleton->lock->unlock();
-#endif
+				GDScriptLanguage::singleton->lock.unlock();
 #ifdef DEBUG_ENABLED
 				gdfs->state.function_name = name;
 				gdfs->state.script_path = _script->get_path();
@@ -1776,14 +1772,9 @@ GDScriptFunction::GDScriptFunction() :
 #ifdef DEBUG_ENABLED
 	_func_cname = NULL;
 
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->lock();
-	}
+	GDScriptLanguage::get_singleton()->lock.lock();
 	GDScriptLanguage::get_singleton()->function_list.add(&function_list);
-
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->unlock();
-	}
+	GDScriptLanguage::get_singleton()->lock.unlock();
 
 	profile.call_count = 0;
 	profile.self_time = 0;
@@ -1800,14 +1791,9 @@ GDScriptFunction::GDScriptFunction() :
 
 GDScriptFunction::~GDScriptFunction() {
 #ifdef DEBUG_ENABLED
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->lock();
-	}
+	GDScriptLanguage::get_singleton()->lock.lock();
 	GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
-
-	if (GDScriptLanguage::get_singleton()->lock) {
-		GDScriptLanguage::get_singleton()->lock->unlock();
-	}
+	GDScriptLanguage::get_singleton()->lock.unlock();
 #endif
 }
 
@@ -1958,12 +1944,8 @@ GDScriptFunctionState::GDScriptFunctionState() :
 GDScriptFunctionState::~GDScriptFunctionState() {
 
 	_clear_stack();
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->lock();
-#endif
+	GDScriptLanguage::singleton->lock.lock();
 	scripts_list.remove_from_list();
 	instances_list.remove_from_list();
-#ifndef NO_THREADS
-	GDScriptLanguage::singleton->lock->unlock();
-#endif
+	GDScriptLanguage::singleton->lock.unlock();
 }

+ 14 - 56
modules/mono/csharp_script.cpp

@@ -57,7 +57,6 @@
 #include "mono_gd/gd_mono_utils.h"
 #include "signal_awaiter_utils.h"
 #include "utils/macros.h"
-#include "utils/mutex_utils.h"
 #include "utils/string_utils.h"
 #include "utils/thread_local.h"
 
@@ -638,7 +637,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
 
 void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
 #ifdef DEBUG_ENABLED
-	SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
+	MutexLock lock(unsafe_object_references_lock);
 	ObjectID id = p_obj->get_instance_id();
 	unsafe_object_references[id]++;
 #endif
@@ -646,7 +645,7 @@ void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
 
 void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
 #ifdef DEBUG_ENABLED
-	SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
+	MutexLock lock(unsafe_object_references_lock);
 	ObjectID id = p_obj->get_instance_id();
 	Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
 	ERR_FAIL_NULL(elem);
@@ -769,7 +768,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
 	List<Ref<CSharpScript> > scripts;
 
 	{
-		SCOPED_MUTEX_LOCK(script_instances_mutex);
+		MutexLock lock(script_instances_mutex);
 
 		for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) {
 			// Cast to CSharpScript to avoid being erased by accident
@@ -1209,7 +1208,7 @@ void CSharpLanguage::set_language_index(int p_idx) {
 void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
 
 	if (!p_gchandle->is_released()) { // Do not lock unnecessarily
-		SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
+		MutexLock lock(get_singleton()->script_gchandle_release_mutex);
 		p_gchandle->release();
 	}
 }
@@ -1219,7 +1218,7 @@ void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<Mon
 	uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it
 
 	if (!p_gchandle->is_released()) { // Do not lock unnecessarily
-		SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
+		MutexLock lock(get_singleton()->script_gchandle_release_mutex);
 
 		MonoObject *target = p_gchandle->get_target();
 
@@ -1244,24 +1243,6 @@ CSharpLanguage::CSharpLanguage() {
 
 	gdmono = NULL;
 
-#ifdef NO_THREADS
-	script_instances_mutex = NULL;
-	script_gchandle_release_mutex = NULL;
-	language_bind_mutex = NULL;
-#else
-	script_instances_mutex = Mutex::create();
-	script_gchandle_release_mutex = Mutex::create();
-	language_bind_mutex = Mutex::create();
-#endif
-
-#ifdef DEBUG_ENABLED
-#ifdef NO_THREADS
-	unsafe_object_references_lock = NULL;
-#else
-	unsafe_object_references_lock = Mutex::create();
-#endif
-#endif
-
 	lang_idx = -1;
 
 	scripts_metadata_invalidated = true;
@@ -1274,29 +1255,6 @@ CSharpLanguage::CSharpLanguage() {
 CSharpLanguage::~CSharpLanguage() {
 
 	finish();
-
-	if (script_instances_mutex) {
-		memdelete(script_instances_mutex);
-		script_instances_mutex = NULL;
-	}
-
-	if (language_bind_mutex) {
-		memdelete(language_bind_mutex);
-		language_bind_mutex = NULL;
-	}
-
-	if (script_gchandle_release_mutex) {
-		memdelete(script_gchandle_release_mutex);
-		script_gchandle_release_mutex = NULL;
-	}
-
-#ifdef DEBUG_ENABLED
-	if (unsafe_object_references_lock) {
-		memdelete(unsafe_object_references_lock);
-		unsafe_object_references_lock = NULL;
-	}
-#endif
-
 	singleton = NULL;
 }
 
@@ -1351,7 +1309,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
 
 void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
 
-	SCOPED_MUTEX_LOCK(language_bind_mutex);
+	MutexLock lock(language_bind_mutex);
 
 	Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
 	if (match)
@@ -1386,7 +1344,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
 	GD_MONO_ASSERT_THREAD_ATTACHED;
 
 	{
-		SCOPED_MUTEX_LOCK(language_bind_mutex);
+		MutexLock lock(language_bind_mutex);
 
 		Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
 
@@ -2216,7 +2174,7 @@ CSharpInstance::~CSharpInstance() {
 		CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
 
 		if (!script_binding.inited) {
-			SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+			MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
 
 			if (!script_binding.inited) { // Other thread may have set it up
 				// Already had a binding that needs to be setup
@@ -2232,7 +2190,7 @@ CSharpInstance::~CSharpInstance() {
 	}
 
 	if (script.is_valid() && owner) {
-		SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+		MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
 
 #ifdef DEBUG_ENABLED
 		// CSharpInstance must not be created unless it's going to be added to the list for sure
@@ -3034,7 +2992,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
 		instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
 
 	{
-		SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+		MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
 		instances.insert(instance->owner);
 	}
 
@@ -3122,7 +3080,7 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t
 
 bool CSharpScript::instance_has(const Object *p_this) const {
 
-	SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+	MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
 	return instances.has((Object *)p_this);
 }
 
@@ -3195,7 +3153,7 @@ Error CSharpScript::reload(bool p_keep_state) {
 
 	bool has_instances;
 	{
-		SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+		MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
 		has_instances = instances.size();
 	}
 
@@ -3394,7 +3352,7 @@ CSharpScript::CSharpScript() :
 
 #ifdef DEBUG_ENABLED
 	{
-		SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+		MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
 		CSharpLanguage::get_singleton()->script_list.add(&this->script_list);
 	}
 #endif
@@ -3403,7 +3361,7 @@ CSharpScript::CSharpScript() :
 CSharpScript::~CSharpScript() {
 
 #ifdef DEBUG_ENABLED
-	SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+	MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
 	CSharpLanguage::get_singleton()->script_list.remove(&this->script_list);
 #endif
 }

+ 5 - 5
modules/mono/csharp_script.h

@@ -307,16 +307,16 @@ class CSharpLanguage : public ScriptLanguage {
 	GDMono *gdmono;
 	SelfList<CSharpScript>::List script_list;
 
-	Mutex *script_instances_mutex;
-	Mutex *script_gchandle_release_mutex;
-	Mutex *language_bind_mutex;
+	Mutex script_instances_mutex;
+	Mutex script_gchandle_release_mutex;
+	Mutex language_bind_mutex;
 
 	Map<Object *, CSharpScriptBinding> script_bindings;
 
 #ifdef DEBUG_ENABLED
 	// List of unsafe object references
 	Map<ObjectID, int> unsafe_object_references;
-	Mutex *unsafe_object_references_lock;
+	Mutex unsafe_object_references_lock;
 #endif
 
 	struct StringNameCache {
@@ -358,7 +358,7 @@ class CSharpLanguage : public ScriptLanguage {
 public:
 	StringNameCache string_names;
 
-	Mutex *get_language_bind_mutex() { return language_bind_mutex; }
+	Mutex &get_language_bind_mutex() { return language_bind_mutex; }
 
 	_FORCE_INLINE_ int get_language_index() { return lang_idx; }
 	void set_language_index(int p_idx);

+ 1 - 2
modules/mono/mono_gd/gd_mono_utils.cpp

@@ -44,7 +44,6 @@
 
 #include "../csharp_script.h"
 #include "../utils/macros.h"
-#include "../utils/mutex_utils.h"
 #include "gd_mono.h"
 #include "gd_mono_cache.h"
 #include "gd_mono_class.h"
@@ -75,7 +74,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
 	CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
 
 	if (!script_binding.inited) {
-		SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+		MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
 
 		if (!script_binding.inited) { // Other thread may have set it up
 			// Already had a binding that needs to be setup

+ 0 - 67
modules/mono/utils/mutex_utils.h

@@ -1,67 +0,0 @@
-/*************************************************************************/
-/*  mutex_utils.h                                                        */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef MUTEX_UTILS_H
-#define MUTEX_UTILS_H
-
-#include "core/error_macros.h"
-#include "core/os/mutex.h"
-
-#include "macros.h"
-
-class ScopedMutexLock {
-	Mutex *mutex;
-
-public:
-	ScopedMutexLock(Mutex *mutex) {
-		this->mutex = mutex;
-#ifndef NO_THREADS
-#ifdef DEBUG_ENABLED
-		CRASH_COND(!mutex);
-#endif
-		this->mutex->lock();
-#endif
-	}
-
-	~ScopedMutexLock() {
-#ifndef NO_THREADS
-#ifdef DEBUG_ENABLED
-		CRASH_COND(!mutex);
-#endif
-		mutex->unlock();
-#endif
-	}
-};
-
-#define SCOPED_MUTEX_LOCK(m_mutex) ScopedMutexLock GD_UNIQUE_NAME(__scoped_mutex_lock__)(m_mutex);
-
-// TODO: Add version that receives a lambda instead, once C++11 is allowed
-
-#endif // MUTEX_UTILS_H

+ 4 - 18
modules/visual_script/visual_script.cpp

@@ -926,13 +926,9 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
 	VisualScriptInstance *instance = memnew(VisualScriptInstance);
 	instance->create(Ref<VisualScript>(this), p_this);
 
-	if (VisualScriptLanguage::singleton->lock)
-		VisualScriptLanguage::singleton->lock->lock();
-
+	VisualScriptLanguage::singleton->lock.lock();
 	instances[p_this] = instance;
-
-	if (VisualScriptLanguage::singleton->lock)
-		VisualScriptLanguage::singleton->lock->unlock();
+	VisualScriptLanguage::singleton->lock.unlock();
 
 	return instance;
 }
@@ -2298,13 +2294,9 @@ VisualScriptInstance::VisualScriptInstance() {
 
 VisualScriptInstance::~VisualScriptInstance() {
 
-	if (VisualScriptLanguage::singleton->lock)
-		VisualScriptLanguage::singleton->lock->lock();
-
+	VisualScriptLanguage::singleton->lock.lock();
 	script->instances.erase(owner);
-
-	if (VisualScriptLanguage::singleton->lock)
-		VisualScriptLanguage::singleton->lock->unlock();
+	VisualScriptLanguage::singleton->lock.unlock();
 
 	for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) {
 		memdelete(E->get());
@@ -2743,9 +2735,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
 	_step = "_step";
 	_subcall = "_subcall";
 	singleton = this;
-#ifndef NO_THREADS
-	lock = Mutex::create();
-#endif
 
 	_debug_parse_err_node = -1;
 	_debug_parse_err_file = "";
@@ -2766,9 +2755,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
 
 VisualScriptLanguage::~VisualScriptLanguage() {
 
-	if (lock)
-		memdelete(lock);
-
 	if (_call_stack) {
 		memdelete_arr(_call_stack);
 	}

+ 1 - 1
modules/visual_script/visual_script.h

@@ -507,7 +507,7 @@ public:
 
 	static VisualScriptLanguage *singleton;
 
-	Mutex *lock;
+	Mutex lock;
 
 	bool debug_break(const String &p_error, bool p_allow_continue = true);
 	bool debug_break_parse(const String &p_file, int p_node, const String &p_error);

+ 5 - 8
platform/android/audio_driver_jandroid.cpp

@@ -48,7 +48,7 @@ int AudioDriverAndroid::mix_rate = 44100;
 bool AudioDriverAndroid::quit = false;
 jobject AudioDriverAndroid::audioBuffer = NULL;
 void *AudioDriverAndroid::audioBufferPinned = NULL;
-Mutex *AudioDriverAndroid::mutex = NULL;
+Mutex AudioDriverAndroid::mutex;
 int32_t *AudioDriverAndroid::audioBuffer32 = NULL;
 
 const char *AudioDriverAndroid::get_name() const {
@@ -58,7 +58,6 @@ const char *AudioDriverAndroid::get_name() const {
 
 Error AudioDriverAndroid::init() {
 
-	mutex = Mutex::create();
 	/*
 	// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
 	   this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
@@ -133,7 +132,7 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) {
 		int16_t *ptr = (int16_t *)audioBufferPinned;
 		int fc = audioBufferFrames;
 
-		if (!s_ad->active || mutex->try_lock() != OK) {
+		if (!s_ad->active || mutex.try_lock() != OK) {
 
 			for (int i = 0; i < fc; i++) {
 				ptr[i] = 0;
@@ -143,7 +142,7 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) {
 
 			s_ad->audio_server_process(fc / 2, audioBuffer32);
 
-			mutex->unlock();
+			mutex.unlock();
 
 			for (int i = 0; i < fc; i++) {
 
@@ -167,14 +166,12 @@ AudioDriver::SpeakerMode AudioDriverAndroid::get_speaker_mode() const {
 
 void AudioDriverAndroid::lock() {
 
-	if (mutex)
-		mutex->lock();
+	mutex.lock();
 }
 
 void AudioDriverAndroid::unlock() {
 
-	if (mutex)
-		mutex->unlock();
+	mutex.unlock();
 }
 
 void AudioDriverAndroid::finish() {

+ 1 - 1
platform/android/audio_driver_jandroid.h

@@ -37,7 +37,7 @@
 
 class AudioDriverAndroid : public AudioDriver {
 
-	static Mutex *mutex;
+	static Mutex mutex;
 	static AudioDriverAndroid *s_ad;
 	static jobject io;
 	static jmethodID _init_audio;

+ 8 - 10
platform/android/audio_driver_opensl.cpp

@@ -44,8 +44,8 @@ void AudioDriverOpenSL::_buffer_callback(
 
 	if (pause) {
 		mix = false;
-	} else if (mutex) {
-		mix = mutex->try_lock() == OK;
+	} else {
+		mix = mutex.try_lock() == OK;
 	}
 
 	if (mix) {
@@ -58,8 +58,8 @@ void AudioDriverOpenSL::_buffer_callback(
 		}
 	}
 
-	if (mutex && mix)
-		mutex->unlock();
+	if (mix)
+		mutex.unlock();
 
 	const int32_t *src_buff = mixdown_buffer;
 
@@ -107,7 +107,6 @@ Error AudioDriverOpenSL::init() {
 
 void AudioDriverOpenSL::start() {
 
-	mutex = Mutex::create();
 	active = false;
 
 	SLresult res;
@@ -329,14 +328,14 @@ AudioDriver::SpeakerMode AudioDriverOpenSL::get_speaker_mode() const {
 
 void AudioDriverOpenSL::lock() {
 
-	if (active && mutex)
-		mutex->lock();
+	if (active)
+		mutex.lock();
 }
 
 void AudioDriverOpenSL::unlock() {
 
-	if (active && mutex)
-		mutex->unlock();
+	if (active)
+		mutex.unlock();
 }
 
 void AudioDriverOpenSL::finish() {
@@ -359,7 +358,6 @@ void AudioDriverOpenSL::set_pause(bool p_pause) {
 
 AudioDriverOpenSL::AudioDriverOpenSL() {
 	s_ad = this;
-	mutex = Mutex::create(); //NULL;
 	pause = false;
 	active = false;
 }

+ 1 - 1
platform/android/audio_driver_opensl.h

@@ -40,7 +40,7 @@
 class AudioDriverOpenSL : public AudioDriver {
 
 	bool active;
-	Mutex *mutex;
+	Mutex mutex;
 
 	enum {
 

+ 15 - 19
platform/android/export/export.cpp

@@ -268,10 +268,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 	String last_plugin_names;
 	uint64_t last_custom_build_time = 0;
 	volatile bool plugins_changed;
-	Mutex *plugins_lock;
+	Mutex plugins_lock;
 	Vector<Device> devices;
 	volatile bool devices_changed;
-	Mutex *device_lock;
+	Mutex device_lock;
 	Thread *check_for_changes_thread;
 	volatile bool quit_request;
 
@@ -285,7 +285,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 				if (!ea->plugins_changed) {
 					Vector<PluginConfigAndroid> loaded_plugins = get_plugins();
 
-					ea->plugins_lock->lock();
+					ea->plugins_lock.lock();
 
 					if (ea->plugins.size() != loaded_plugins.size()) {
 						ea->plugins_changed = true;
@@ -302,7 +302,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 						ea->plugins = loaded_plugins;
 					}
 
-					ea->plugins_lock->unlock();
+					ea->plugins_lock.unlock();
 				}
 			}
 
@@ -328,7 +328,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 					ldevices.push_back(d);
 				}
 
-				ea->device_lock->lock();
+				ea->device_lock.lock();
 
 				bool different = false;
 
@@ -418,7 +418,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 					ea->devices_changed = true;
 				}
 
-				ea->device_lock->unlock();
+				ea->device_lock.unlock();
 			}
 
 			uint64_t sleep = OS::get_singleton()->get_power_state() == OS::POWERSTATE_ON_BATTERY ? 1000 : 100;
@@ -1770,9 +1770,9 @@ public:
 
 	virtual int get_options_count() const {
 
-		device_lock->lock();
+		device_lock.lock();
 		int dc = devices.size();
-		device_lock->unlock();
+		device_lock.unlock();
 
 		return dc;
 	}
@@ -1785,16 +1785,16 @@ public:
 	virtual String get_option_label(int p_index) const {
 
 		ERR_FAIL_INDEX_V(p_index, devices.size(), "");
-		device_lock->lock();
+		device_lock.lock();
 		String s = devices[p_index].name;
-		device_lock->unlock();
+		device_lock.unlock();
 		return s;
 	}
 
 	virtual String get_option_tooltip(int p_index) const {
 
 		ERR_FAIL_INDEX_V(p_index, devices.size(), "");
-		device_lock->lock();
+		device_lock.lock();
 		String s = devices[p_index].description;
 		if (devices.size() == 1) {
 			// Tooltip will be:
@@ -1802,7 +1802,7 @@ public:
 			// Description
 			s = devices[p_index].name + "\n\n" + s;
 		}
-		device_lock->unlock();
+		device_lock.unlock();
 		return s;
 	}
 
@@ -1817,7 +1817,7 @@ public:
 			return ERR_UNCONFIGURED;
 		}
 
-		device_lock->lock();
+		device_lock.lock();
 
 		EditorProgress ep("run", "Running on " + devices[p_device].name, 3);
 
@@ -1825,7 +1825,7 @@ public:
 
 		// Export_temp APK.
 		if (ep.step("Exporting APK...", 0)) {
-			device_lock->unlock();
+			device_lock.unlock();
 			return ERR_SKIP;
 		}
 
@@ -1840,7 +1840,7 @@ public:
 #define CLEANUP_AND_RETURN(m_err)                         \
 	{                                                     \
 		DirAccess::remove_file_or_error(tmp_export_path); \
-		device_lock->unlock();                            \
+		device_lock.unlock();                             \
 		return m_err;                                     \
 	}
 
@@ -3280,10 +3280,8 @@ public:
 		run_icon.instance();
 		run_icon->create_from_image(img);
 
-		device_lock = Mutex::create();
 		devices_changed = true;
 
-		plugins_lock = Mutex::create();
 		plugins_changed = true;
 		quit_request = false;
 		check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
@@ -3292,8 +3290,6 @@ public:
 	~EditorExportPlatformAndroid() {
 		quit_request = true;
 		Thread::wait_to_finish(check_for_changes_thread);
-		memdelete(plugins_lock);
-		memdelete(device_lock);
 		memdelete(check_for_changes_thread);
 	}
 };

+ 3 - 5
platform/iphone/export/export.cpp

@@ -58,7 +58,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
 	volatile bool plugins_changed;
 	Thread *check_for_changes_thread;
 	volatile bool quit_request;
-	Mutex *plugins_lock;
+	Mutex plugins_lock;
 	Vector<PluginConfigIOS> plugins;
 
 	typedef Error (*FileHandler)(String p_file, void *p_userdata);
@@ -148,7 +148,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
 			// Nothing to do if we already know the plugins have changed.
 			if (!ea->plugins_changed) {
 
-				ea->plugins_lock->lock();
+				ea->plugins_lock.lock();
 
 				Vector<PluginConfigIOS> loaded_plugins = get_plugins();
 
@@ -163,7 +163,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
 					}
 				}
 
-				ea->plugins_lock->unlock();
+				ea->plugins_lock.unlock();
 			}
 
 			uint64_t wait = 3000000;
@@ -1838,7 +1838,6 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() {
 
 	plugins_changed = true;
 	quit_request = false;
-	plugins_lock = Mutex::create();
 
 	check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
 }
@@ -1846,7 +1845,6 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() {
 EditorExportPlatformIOS::~EditorExportPlatformIOS() {
 	quit_request = true;
 	Thread::wait_to_finish(check_for_changes_thread);
-	memdelete(plugins_lock);
 	memdelete(check_for_changes_thread);
 }
 

+ 2 - 9
platform/javascript/audio_driver_javascript.cpp

@@ -267,20 +267,15 @@ int AudioDriverJavaScript::WorkletNode::create(int p_buffer_size, int p_channels
 
 void AudioDriverJavaScript::WorkletNode::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
 	godot_audio_worklet_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, state);
-	mutex = Mutex::create();
 	thread = Thread::create(_audio_thread_func, this);
 }
 
 void AudioDriverJavaScript::WorkletNode::lock() {
-	if (mutex) {
-		mutex->lock();
-	}
+	mutex.lock();
 }
 
 void AudioDriverJavaScript::WorkletNode::unlock() {
-	if (mutex) {
-		mutex->unlock();
-	}
+	mutex.unlock();
 }
 
 void AudioDriverJavaScript::WorkletNode::finish() {
@@ -288,7 +283,5 @@ void AudioDriverJavaScript::WorkletNode::finish() {
 	Thread::wait_to_finish(thread);
 	memdelete(thread);
 	thread = nullptr;
-	memdelete(mutex);
-	mutex = nullptr;
 }
 #endif

+ 1 - 1
platform/javascript/audio_driver_javascript.h

@@ -58,7 +58,7 @@ public:
 			STATE_SAMPLES_OUT,
 			STATE_MAX,
 		};
-		Mutex *mutex = nullptr;
+		Mutex mutex;
 		Thread *thread = nullptr;
 		bool quit = false;
 		int32_t state[STATE_MAX] = { 0 };

+ 9 - 11
platform/javascript/export/export.cpp

@@ -212,7 +212,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
 
 	Ref<EditorHTTPServer> server;
 	bool server_quit = false;
-	Mutex *server_lock = NULL;
+	Mutex server_lock;
 	Thread *server_thread = NULL;
 
 	enum ExportMode {
@@ -610,9 +610,9 @@ bool EditorExportPlatformJavaScript::poll_export() {
 	menu_options = preset.is_valid();
 	if (server->is_listening()) {
 		if (menu_options == 0) {
-			server_lock->lock();
+			server_lock.lock();
 			server->stop();
-			server_lock->unlock();
+			server_lock.unlock();
 		} else {
 			menu_options += 1;
 		}
@@ -632,9 +632,9 @@ int EditorExportPlatformJavaScript::get_options_count() const {
 Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) {
 
 	if (p_option == 1) {
-		server_lock->lock();
+		server_lock.lock();
 		server->stop();
-		server_lock->unlock();
+		server_lock.unlock();
 		return OK;
 	}
 
@@ -666,10 +666,10 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
 	ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + bind_host + "'. Try using '127.0.0.1'.");
 
 	// Restart server.
-	server_lock->lock();
+	server_lock.lock();
 	server->stop();
 	err = server->listen(bind_port, bind_ip);
-	server_lock->unlock();
+	server_lock.unlock();
 	ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to start HTTP server.");
 
 	OS::get_singleton()->shell_open(String("http://" + bind_host + ":" + itos(bind_port) + "/tmp_js_export.html"));
@@ -687,16 +687,15 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) {
 	EditorExportPlatformJavaScript *ej = (EditorExportPlatformJavaScript *)data;
 	while (!ej->server_quit) {
 		OS::get_singleton()->delay_usec(1000);
-		ej->server_lock->lock();
+		ej->server_lock.lock();
 		ej->server->poll();
-		ej->server_lock->unlock();
+		ej->server_lock.unlock();
 	}
 }
 
 EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
 
 	server.instance();
-	server_lock = Mutex::create();
 	server_thread = Thread::create(_server_thread_poll, this);
 
 	Ref<Image> img = memnew(Image(_javascript_logo));
@@ -718,7 +717,6 @@ EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
 	server->stop();
 	server_quit = true;
 	Thread::wait_to_finish(server_thread);
-	memdelete(server_lock);
 	memdelete(server_thread);
 }
 

+ 0 - 2
platform/uwp/os_uwp.cpp

@@ -40,7 +40,6 @@
 #include "drivers/unix/ip_unix.h"
 #include "drivers/windows/dir_access_windows.h"
 #include "drivers/windows/file_access_windows.h"
-#include "drivers/windows/mutex_windows.h"
 #include "drivers/windows/semaphore_windows.h"
 #include "main/main.h"
 #include "platform/windows/windows_terminal_logger.h"
@@ -141,7 +140,6 @@ void OS_UWP::initialize_core() {
 
 	ThreadUWP::make_default();
 	SemaphoreWindows::make_default();
-	MutexWindows::make_default();
 
 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);

+ 0 - 2
platform/windows/os_windows.cpp

@@ -40,7 +40,6 @@
 #include "drivers/gles3/rasterizer_gles3.h"
 #include "drivers/windows/dir_access_windows.h"
 #include "drivers/windows/file_access_windows.h"
-#include "drivers/windows/mutex_windows.h"
 #include "drivers/windows/semaphore_windows.h"
 #include "drivers/windows/thread_windows.h"
 #include "joypad_windows.h"
@@ -228,7 +227,6 @@ void OS_Windows::initialize_core() {
 
 	ThreadWindows::make_default();
 	SemaphoreWindows::make_default();
-	MutexWindows::make_default();
 
 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
 	FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);

+ 8 - 10
platform/x11/joypad_linux.cpp

@@ -94,7 +94,6 @@ JoypadLinux::JoypadLinux(InputDefault *in) {
 #endif
 	exit_monitor = false;
 	input = in;
-	joy_mutex = Mutex::create();
 	joy_thread = Thread::create(joy_thread_func, this);
 }
 
@@ -102,7 +101,6 @@ JoypadLinux::~JoypadLinux() {
 	exit_monitor = true;
 	Thread::wait_to_finish(joy_thread);
 	memdelete(joy_thread);
-	memdelete(joy_mutex);
 	close_joypad();
 }
 
@@ -157,9 +155,9 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
 
 			String devnode_str = devnode;
 			if (devnode_str.find(ignore_str) == -1) {
-				joy_mutex->lock();
+				joy_mutex.lock();
 				open_joypad(devnode);
-				joy_mutex->unlock();
+				joy_mutex.unlock();
 			}
 		}
 		udev_device_unref(dev);
@@ -196,7 +194,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
 
 			if (dev && udev_device_get_devnode(dev) != 0) {
 
-				joy_mutex->lock();
+				joy_mutex.lock();
 				String action = udev_device_get_action(dev);
 				const char *devnode = udev_device_get_devnode(dev);
 				if (devnode) {
@@ -212,7 +210,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
 				}
 
 				udev_device_unref(dev);
-				joy_mutex->unlock();
+				joy_mutex.unlock();
 			}
 		}
 		usleep(50000);
@@ -224,7 +222,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
 void JoypadLinux::monitor_joypads() {
 
 	while (!exit_monitor) {
-		joy_mutex->lock();
+		joy_mutex.lock();
 
 		DIR *input_directory;
 		input_directory = opendir("/dev/input");
@@ -243,7 +241,7 @@ void JoypadLinux::monitor_joypads() {
 			}
 		}
 		closedir(input_directory);
-		joy_mutex->unlock();
+		joy_mutex.unlock();
 		usleep(1000000); // 1s
 	}
 }
@@ -491,7 +489,7 @@ InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int
 
 void JoypadLinux::process_joypads() {
 
-	if (joy_mutex->try_lock() != OK) {
+	if (joy_mutex.try_lock() != OK) {
 		return;
 	}
 	for (int i = 0; i < JOYPADS_MAX; i++) {
@@ -586,6 +584,6 @@ void JoypadLinux::process_joypads() {
 			}
 		}
 	}
-	joy_mutex->unlock();
+	joy_mutex.unlock();
 }
 #endif

+ 1 - 1
platform/x11/joypad_linux.h

@@ -75,7 +75,7 @@ private:
 	bool use_udev;
 #endif
 	bool exit_monitor;
-	Mutex *joy_mutex;
+	Mutex joy_mutex;
 	Thread *joy_thread;
 	InputDefault *input;
 	Joypad joypads[JOYPADS_MAX];

+ 0 - 4
platform/x11/os_x11.cpp

@@ -122,8 +122,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
 
 	XInitThreads();
 
-	events_mutex = Mutex::create();
-
 	/** XLIB INITIALIZATION **/
 	x11_display = XOpenDisplay(NULL);
 
@@ -879,8 +877,6 @@ void OS_X11::finalize() {
 	if (xmbstring)
 		memfree(xmbstring);
 
-	memdelete(events_mutex);
-
 	args.clear();
 }
 

+ 1 - 1
platform/x11/os_x11.h

@@ -165,7 +165,7 @@ class OS_X11 : public OS_Unix {
 	String _get_clipboard(Atom p_source, Window x11_window) const;
 	void _clipboard_transfer_ownership(Atom p_source, Window x11_window) const;
 
-	mutable Mutex *events_mutex;
+	mutable Mutex events_mutex;
 	Thread *events_thread = nullptr;
 	bool events_thread_done = false;
 	LocalVector<XEvent> polled_events;

+ 9 - 25
scene/2d/canvas_item.cpp

@@ -41,17 +41,13 @@
 #include "servers/visual/visual_server_raster.h"
 #include "servers/visual_server.h"
 
-Mutex *CanvasItemMaterial::material_mutex = NULL;
+Mutex CanvasItemMaterial::material_mutex;
 SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL;
 Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map;
 CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL;
 
 void CanvasItemMaterial::init_shaders() {
 
-#ifndef NO_THREADS
-	material_mutex = Mutex::create();
-#endif
-
 	dirty_materials = memnew(SelfList<CanvasItemMaterial>::List);
 
 	shader_names = memnew(ShaderNames);
@@ -66,10 +62,6 @@ void CanvasItemMaterial::finish_shaders() {
 	memdelete(dirty_materials);
 	memdelete(shader_names);
 	dirty_materials = NULL;
-
-#ifndef NO_THREADS
-	memdelete(material_mutex);
-#endif
 }
 
 void CanvasItemMaterial::_update_shader() {
@@ -156,42 +148,36 @@ void CanvasItemMaterial::_update_shader() {
 
 void CanvasItemMaterial::flush_changes() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	while (dirty_materials->first()) {
 
 		dirty_materials->first()->self()->_update_shader();
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 void CanvasItemMaterial::_queue_shader_change() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	if (!element.in_list()) {
 		dirty_materials->add(&element);
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 bool CanvasItemMaterial::_is_shader_dirty() const {
 
 	bool dirty = false;
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	dirty = element.in_list();
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 
 	return dirty;
 }
@@ -332,8 +318,7 @@ CanvasItemMaterial::CanvasItemMaterial() :
 
 CanvasItemMaterial::~CanvasItemMaterial() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	if (shader_map.has(current_key)) {
 		shader_map[current_key].users--;
@@ -346,8 +331,7 @@ CanvasItemMaterial::~CanvasItemMaterial() {
 		VS::get_singleton()->material_set_shader(_get_material(), RID());
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 ///////////////////////////////////////////////////////////////////

+ 1 - 1
scene/2d/canvas_item.h

@@ -108,7 +108,7 @@ private:
 		return mk;
 	}
 
-	static Mutex *material_mutex;
+	static Mutex material_mutex;
 	static SelfList<CanvasItemMaterial>::List *dirty_materials;
 	SelfList<CanvasItemMaterial> element;
 

+ 6 - 28
scene/2d/cpu_particles_2d.cpp

@@ -980,9 +980,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
 }
 
 void CPUParticles2D::_update_particle_data_buffer() {
-#ifndef NO_THREADS
-	update_mutex->lock();
-#endif
+	update_mutex.lock();
 
 	{
 
@@ -1050,18 +1048,14 @@ void CPUParticles2D::_update_particle_data_buffer() {
 		}
 	}
 
-#ifndef NO_THREADS
-	update_mutex->unlock();
-#endif
+	update_mutex.unlock();
 }
 
 void CPUParticles2D::_set_redraw(bool p_redraw) {
 	if (redraw == p_redraw)
 		return;
 	redraw = p_redraw;
-#ifndef NO_THREADS
-	update_mutex->lock();
-#endif
+	update_mutex.lock();
 	if (redraw) {
 		VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
 		VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
@@ -1075,23 +1069,15 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
 
 		VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
 	}
-#ifndef NO_THREADS
-	update_mutex->unlock();
-#endif
+	update_mutex.unlock();
 	update(); // redraw to update render list
 }
 
 void CPUParticles2D::_update_render_thread() {
 
-#ifndef NO_THREADS
-	update_mutex->lock();
-#endif
-
+	update_mutex.lock();
 	VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
-
-#ifndef NO_THREADS
-	update_mutex->unlock();
-#endif
+	update_mutex.unlock();
 }
 
 void CPUParticles2D::_notification(int p_what) {
@@ -1504,18 +1490,10 @@ CPUParticles2D::CPUParticles2D() {
 
 	set_color(Color(1, 1, 1, 1));
 
-#ifndef NO_THREADS
-	update_mutex = Mutex::create();
-#endif
-
 	_update_mesh_texture();
 }
 
 CPUParticles2D::~CPUParticles2D() {
 	VS::get_singleton()->free(multimesh);
 	VS::get_singleton()->free(mesh);
-
-#ifndef NO_THREADS
-	memdelete(update_mutex);
-#endif
 }

+ 1 - 1
scene/2d/cpu_particles_2d.h

@@ -180,7 +180,7 @@ private:
 	void _particles_process(float p_delta);
 	void _update_particle_data_buffer();
 
-	Mutex *update_mutex;
+	Mutex update_mutex;
 
 	void _update_render_thread();
 

+ 7 - 26
scene/3d/cpu_particles.cpp

@@ -1024,9 +1024,7 @@ void CPUParticles::_particles_process(float p_delta) {
 }
 
 void CPUParticles::_update_particle_data_buffer() {
-#ifndef NO_THREADS
-	update_mutex->lock();
-#endif
+	update_mutex.lock();
 
 	{
 
@@ -1118,18 +1116,14 @@ void CPUParticles::_update_particle_data_buffer() {
 		can_update = true;
 	}
 
-#ifndef NO_THREADS
-	update_mutex->unlock();
-#endif
+	update_mutex.unlock();
 }
 
 void CPUParticles::_set_redraw(bool p_redraw) {
 	if (redraw == p_redraw)
 		return;
 	redraw = p_redraw;
-#ifndef NO_THREADS
-	update_mutex->lock();
-#endif
+	update_mutex.lock();
 	if (redraw) {
 		VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
 		VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
@@ -1141,24 +1135,19 @@ void CPUParticles::_set_redraw(bool p_redraw) {
 		VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
 		VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
 	}
-#ifndef NO_THREADS
-	update_mutex->unlock();
-#endif
+	update_mutex.unlock();
 }
 
 void CPUParticles::_update_render_thread() {
 
-#ifndef NO_THREADS
-	update_mutex->lock();
-#endif
+	update_mutex.lock();
+
 	if (can_update) {
 		VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
 		can_update = false; //wait for next time
 	}
 
-#ifndef NO_THREADS
-	update_mutex->unlock();
-#endif
+	update_mutex.unlock();
 }
 
 void CPUParticles::_notification(int p_what) {
@@ -1564,16 +1553,8 @@ CPUParticles::CPUParticles() {
 	can_update = false;
 
 	set_color(Color(1, 1, 1, 1));
-
-#ifndef NO_THREADS
-	update_mutex = Mutex::create();
-#endif
 }
 
 CPUParticles::~CPUParticles() {
 	VS::get_singleton()->free(multimesh);
-
-#ifndef NO_THREADS
-	memdelete(update_mutex);
-#endif
 }

+ 1 - 1
scene/3d/cpu_particles.h

@@ -179,7 +179,7 @@ private:
 	void _particles_process(float p_delta);
 	void _update_particle_data_buffer();
 
-	Mutex *update_mutex;
+	Mutex update_mutex;
 
 	void _update_render_thread();
 

+ 8 - 10
scene/debugger/script_debugger_remote.cpp

@@ -378,7 +378,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
 
 void ScriptDebuggerRemote::_get_output() {
 
-	mutex->lock();
+	mutex.lock();
 	if (output_strings.size()) {
 
 		locking = true;
@@ -473,7 +473,7 @@ void ScriptDebuggerRemote::_get_output() {
 		errors.pop_front();
 		locking = false;
 	}
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void ScriptDebuggerRemote::line_poll() {
@@ -1055,7 +1055,7 @@ void ScriptDebuggerRemote::_send_network_bandwidth_usage() {
 
 void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) {
 
-	mutex->lock();
+	mutex.lock();
 	if (!locking && tcp_client->is_connected_to_host()) {
 
 		if (messages.size() >= max_messages_per_frame) {
@@ -1067,7 +1067,7 @@ void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_
 			messages.push_back(msg);
 		}
 	}
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info) {
@@ -1113,7 +1113,7 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
 		err_count++;
 	}
 
-	mutex->lock();
+	mutex.lock();
 
 	if (!locking && tcp_client->is_connected_to_host()) {
 
@@ -1132,7 +1132,7 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
 		}
 	}
 
-	mutex->unlock();
+	mutex.unlock();
 }
 
 void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) {
@@ -1161,7 +1161,7 @@ void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string,
 	sdr->char_count += allowed_chars;
 	bool overflowed = sdr->char_count >= sdr->max_cps;
 
-	sdr->mutex->lock();
+	sdr->mutex.lock();
 	if (!sdr->locking && sdr->tcp_client->is_connected_to_host()) {
 
 		if (overflowed)
@@ -1178,7 +1178,7 @@ void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string,
 			sdr->output_strings.push_back(output_string);
 		}
 	}
-	sdr->mutex->unlock();
+	sdr->mutex.unlock();
 }
 
 void ScriptDebuggerRemote::request_quit() {
@@ -1254,7 +1254,6 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
 		last_net_bandwidth_time(0),
 		performance(Engine::get_singleton()->get_singleton_object("Performance")),
 		requested_quit(false),
-		mutex(Mutex::create()),
 		max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
 		n_messages_dropped(0),
 		max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")),
@@ -1291,5 +1290,4 @@ ScriptDebuggerRemote::~ScriptDebuggerRemote() {
 
 	remove_print_handler(&phl);
 	remove_error_handler(&eh);
-	memdelete(mutex);
 }

+ 1 - 1
scene/debugger/script_debugger_remote.h

@@ -75,7 +75,7 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 	uint64_t last_net_bandwidth_time;
 	Object *performance;
 	bool requested_quit;
-	Mutex *mutex;
+	Mutex mutex;
 
 	struct OutputError {
 

+ 9 - 18
scene/resources/dynamic_font.cpp

@@ -1040,7 +1040,7 @@ void DynamicFont::_bind_methods() {
 	BIND_ENUM_CONSTANT(SPACING_SPACE);
 }
 
-Mutex *DynamicFont::dynamic_font_mutex = NULL;
+Mutex DynamicFont::dynamic_font_mutex;
 
 SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL;
 
@@ -1054,29 +1054,22 @@ DynamicFont::DynamicFont() :
 	spacing_char = 0;
 	spacing_space = 0;
 	outline_color = Color(1, 1, 1);
-	if (dynamic_font_mutex) {
-		dynamic_font_mutex->lock();
-		dynamic_fonts->add(&font_list);
-		dynamic_font_mutex->unlock();
-	}
+	dynamic_font_mutex.lock();
+	dynamic_fonts->add(&font_list);
+	dynamic_font_mutex.unlock();
 }
 
 DynamicFont::~DynamicFont() {
-	if (dynamic_font_mutex) {
-		dynamic_font_mutex->lock();
-		dynamic_fonts->remove(&font_list);
-		dynamic_font_mutex->unlock();
-	}
+	dynamic_font_mutex.lock();
+	dynamic_fonts->remove(&font_list);
+	dynamic_font_mutex.unlock();
 }
 
 void DynamicFont::initialize_dynamic_fonts() {
 	dynamic_fonts = memnew(SelfList<DynamicFont>::List());
-	dynamic_font_mutex = Mutex::create();
 }
 
 void DynamicFont::finish_dynamic_fonts() {
-	memdelete(dynamic_font_mutex);
-	dynamic_font_mutex = NULL;
 	memdelete(dynamic_fonts);
 	dynamic_fonts = NULL;
 }
@@ -1085,8 +1078,7 @@ void DynamicFont::update_oversampling() {
 
 	Vector<Ref<DynamicFont> > changed;
 
-	if (dynamic_font_mutex)
-		dynamic_font_mutex->lock();
+	dynamic_font_mutex.lock();
 
 	SelfList<DynamicFont> *E = dynamic_fonts->first();
 	while (E) {
@@ -1114,8 +1106,7 @@ void DynamicFont::update_oversampling() {
 		E = E->next();
 	}
 
-	if (dynamic_font_mutex)
-		dynamic_font_mutex->unlock();
+	dynamic_font_mutex.unlock();
 
 	for (int i = 0; i < changed.size(); i++) {
 		changed.write[i]->emit_changed();

+ 1 - 1
scene/resources/dynamic_font.h

@@ -286,7 +286,7 @@ public:
 
 	SelfList<DynamicFont> font_list;
 
-	static Mutex *dynamic_font_mutex;
+	static Mutex dynamic_font_mutex;
 	static SelfList<DynamicFont>::List *dynamic_fonts;
 
 	static void initialize_dynamic_fonts();

+ 9 - 25
scene/resources/material.cpp

@@ -290,17 +290,13 @@ ShaderMaterial::~ShaderMaterial() {
 
 /////////////////////////////////
 
-Mutex *SpatialMaterial::material_mutex = NULL;
+Mutex SpatialMaterial::material_mutex;
 SelfList<SpatialMaterial>::List *SpatialMaterial::dirty_materials = NULL;
 Map<SpatialMaterial::MaterialKey, SpatialMaterial::ShaderData> SpatialMaterial::shader_map;
 SpatialMaterial::ShaderNames *SpatialMaterial::shader_names = NULL;
 
 void SpatialMaterial::init_shaders() {
 
-#ifndef NO_THREADS
-	material_mutex = Mutex::create();
-#endif
-
 	dirty_materials = memnew(SelfList<SpatialMaterial>::List);
 
 	shader_names = memnew(ShaderNames);
@@ -379,10 +375,6 @@ void SpatialMaterial::finish_shaders() {
 		materials_for_2d[i].unref();
 	}
 
-#ifndef NO_THREADS
-	memdelete(material_mutex);
-#endif
-
 	memdelete(dirty_materials);
 	dirty_materials = NULL;
 
@@ -1062,42 +1054,36 @@ void SpatialMaterial::_update_shader() {
 
 void SpatialMaterial::flush_changes() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	while (dirty_materials->first()) {
 
 		dirty_materials->first()->self()->_update_shader();
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 void SpatialMaterial::_queue_shader_change() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	if (!element.in_list()) {
 		dirty_materials->add(&element);
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 bool SpatialMaterial::_is_shader_dirty() const {
 
 	bool dirty = false;
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	dirty = element.in_list();
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 
 	return dirty;
 }
@@ -2425,8 +2411,7 @@ SpatialMaterial::SpatialMaterial() :
 
 SpatialMaterial::~SpatialMaterial() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	if (shader_map.has(current_key)) {
 		shader_map[current_key].users--;
@@ -2439,6 +2424,5 @@ SpatialMaterial::~SpatialMaterial() {
 		VS::get_singleton()->material_set_shader(_get_material(), RID());
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }

+ 1 - 1
scene/resources/material.h

@@ -361,7 +361,7 @@ private:
 		StringName texture_names[TEXTURE_MAX];
 	};
 
-	static Mutex *material_mutex;
+	static Mutex material_mutex;
 	static SelfList<SpatialMaterial>::List *dirty_materials;
 	static ShaderNames *shader_names;
 

+ 9 - 25
scene/resources/particles_material.cpp

@@ -30,17 +30,13 @@
 
 #include "particles_material.h"
 
-Mutex *ParticlesMaterial::material_mutex = NULL;
+Mutex ParticlesMaterial::material_mutex;
 SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL;
 Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map;
 ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL;
 
 void ParticlesMaterial::init_shaders() {
 
-#ifndef NO_THREADS
-	material_mutex = Mutex::create();
-#endif
-
 	dirty_materials = memnew(SelfList<ParticlesMaterial>::List);
 
 	shader_names = memnew(ShaderNames);
@@ -107,10 +103,6 @@ void ParticlesMaterial::init_shaders() {
 
 void ParticlesMaterial::finish_shaders() {
 
-#ifndef NO_THREADS
-	memdelete(material_mutex);
-#endif
-
 	memdelete(dirty_materials);
 	dirty_materials = NULL;
 
@@ -615,42 +607,36 @@ void ParticlesMaterial::_update_shader() {
 
 void ParticlesMaterial::flush_changes() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	while (dirty_materials->first()) {
 
 		dirty_materials->first()->self()->_update_shader();
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 void ParticlesMaterial::_queue_shader_change() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	if (!element.in_list()) {
 		dirty_materials->add(&element);
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }
 
 bool ParticlesMaterial::_is_shader_dirty() const {
 
 	bool dirty = false;
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	dirty = element.in_list();
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 
 	return dirty;
 }
@@ -1301,8 +1287,7 @@ ParticlesMaterial::ParticlesMaterial() :
 
 ParticlesMaterial::~ParticlesMaterial() {
 
-	if (material_mutex)
-		material_mutex->lock();
+	material_mutex.lock();
 
 	if (shader_map.has(current_key)) {
 		shader_map[current_key].users--;
@@ -1315,6 +1300,5 @@ ParticlesMaterial::~ParticlesMaterial() {
 		VS::get_singleton()->material_set_shader(_get_material(), RID());
 	}
 
-	if (material_mutex)
-		material_mutex->unlock();
+	material_mutex.unlock();
 }

+ 1 - 1
scene/resources/particles_material.h

@@ -126,7 +126,7 @@ private:
 		return mk;
 	}
 
-	static Mutex *material_mutex;
+	static Mutex material_mutex;
 	static SelfList<ParticlesMaterial>::List *dirty_materials;
 
 	struct ShaderNames {

+ 4 - 8
servers/audio/audio_driver_dummy.cpp

@@ -49,7 +49,6 @@ Error AudioDriverDummy::init() {
 
 	samples_in = memnew_arr(int32_t, buffer_frames * channels);
 
-	mutex = Mutex::create();
 	thread = Thread::create(AudioDriverDummy::thread_func, this);
 
 	return OK;
@@ -95,16 +94,16 @@ AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const {
 
 void AudioDriverDummy::lock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->lock();
+	mutex.lock();
 };
 
 void AudioDriverDummy::unlock() {
 
-	if (!thread || !mutex)
+	if (!thread)
 		return;
-	mutex->unlock();
+	mutex.unlock();
 };
 
 void AudioDriverDummy::finish() {
@@ -120,14 +119,11 @@ void AudioDriverDummy::finish() {
 	};
 
 	memdelete(thread);
-	if (mutex)
-		memdelete(mutex);
 	thread = NULL;
 };
 
 AudioDriverDummy::AudioDriverDummy() {
 
-	mutex = NULL;
 	thread = NULL;
 };
 

+ 1 - 1
servers/audio/audio_driver_dummy.h

@@ -39,7 +39,7 @@
 class AudioDriverDummy : public AudioDriver {
 
 	Thread *thread;
-	Mutex *mutex;
+	Mutex mutex;
 
 	int32_t *samples_in;
 

+ 5 - 7
servers/audio_server.cpp

@@ -1148,27 +1148,27 @@ void *AudioServer::audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_d
 		copymem(ad, p_from_data, p_data_len);
 	}
 
-	audio_data_lock->lock();
+	audio_data_lock.lock();
 	audio_data[ad] = p_data_len;
 	audio_data_total_mem += p_data_len;
 	audio_data_max_mem = MAX(audio_data_total_mem, audio_data_max_mem);
-	audio_data_lock->unlock();
+	audio_data_lock.unlock();
 
 	return ad;
 }
 
 void AudioServer::audio_data_free(void *p_data) {
 
-	audio_data_lock->lock();
+	audio_data_lock.lock();
 	if (!audio_data.has(p_data)) {
-		audio_data_lock->unlock();
+		audio_data_lock.unlock();
 		ERR_FAIL();
 	}
 
 	audio_data_total_mem -= audio_data[p_data];
 	audio_data.erase(p_data);
 	memfree(p_data);
-	audio_data_lock->unlock();
+	audio_data_lock.unlock();
 }
 
 size_t AudioServer::audio_data_get_total_memory_usage() const {
@@ -1410,7 +1410,6 @@ AudioServer::AudioServer() {
 	singleton = this;
 	audio_data_total_mem = 0;
 	audio_data_max_mem = 0;
-	audio_data_lock = Mutex::create();
 	mix_frames = 0;
 	channel_count = 0;
 	to_mix = 0;
@@ -1424,7 +1423,6 @@ AudioServer::AudioServer() {
 
 AudioServer::~AudioServer() {
 
-	memdelete(audio_data_lock);
 	singleton = NULL;
 }
 

+ 1 - 1
servers/audio_server.h

@@ -238,7 +238,7 @@ private:
 	size_t audio_data_total_mem;
 	size_t audio_data_max_mem;
 
-	Mutex *audio_data_lock;
+	Mutex audio_data_lock;
 
 	void init_channels_and_buffers();
 

+ 0 - 2
servers/physics_2d/physics_2d_server_wrap_mt.cpp

@@ -160,7 +160,6 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool
 	step_sem = NULL;
 	step_pending = 0;
 	step_thread_up = false;
-	alloc_mutex = Mutex::create();
 
 	pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
 
@@ -177,6 +176,5 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool
 Physics2DServerWrapMT::~Physics2DServerWrapMT() {
 
 	memdelete(physics_2d_server);
-	memdelete(alloc_mutex);
 	//finish();
 }

+ 1 - 1
servers/physics_2d/physics_2d_server_wrap_mt.h

@@ -67,7 +67,7 @@ class Physics2DServerWrapMT : public Physics2DServer {
 
 	bool first_frame;
 
-	Mutex *alloc_mutex;
+	Mutex alloc_mutex;
 	int pool_max_size;
 
 public:

+ 12 - 12
servers/server_wrap_mt_common.h

@@ -57,7 +57,7 @@
 	virtual RID m_type##_create() {                                                        \
 		if (Thread::get_caller_id() != server_thread) {                                    \
 			RID rid;                                                                       \
-			alloc_mutex->lock();                                                           \
+			alloc_mutex.lock();                                                            \
 			if (m_type##_id_pool.size() == 0) {                                            \
 				int ret;                                                                   \
 				command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \
@@ -65,7 +65,7 @@
 			}                                                                              \
 			rid = m_type##_id_pool.front()->get();                                         \
 			m_type##_id_pool.pop_front();                                                  \
-			alloc_mutex->unlock();                                                         \
+			alloc_mutex.unlock();                                                          \
 			return rid;                                                                    \
 		} else {                                                                           \
 			return server_name->m_type##_create();                                         \
@@ -88,7 +88,7 @@
 	virtual RID m_type##_create(m_arg1 p1) {                                                   \
 		if (Thread::get_caller_id() != server_thread) {                                        \
 			RID rid;                                                                           \
-			alloc_mutex->lock();                                                               \
+			alloc_mutex.lock();                                                                \
 			if (m_type##_id_pool.size() == 0) {                                                \
 				int ret;                                                                       \
 				command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \
@@ -96,7 +96,7 @@
 			}                                                                                  \
 			rid = m_type##_id_pool.front()->get();                                             \
 			m_type##_id_pool.pop_front();                                                      \
-			alloc_mutex->unlock();                                                             \
+			alloc_mutex.unlock();                                                              \
 			return rid;                                                                        \
 		} else {                                                                               \
 			return server_name->m_type##_create(p1);                                           \
@@ -119,7 +119,7 @@
 	virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) {                                            \
 		if (Thread::get_caller_id() != server_thread) {                                            \
 			RID rid;                                                                               \
-			alloc_mutex->lock();                                                                   \
+			alloc_mutex.lock();                                                                    \
 			if (m_type##_id_pool.size() == 0) {                                                    \
 				int ret;                                                                           \
 				command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \
@@ -127,7 +127,7 @@
 			}                                                                                      \
 			rid = m_type##_id_pool.front()->get();                                                 \
 			m_type##_id_pool.pop_front();                                                          \
-			alloc_mutex->unlock();                                                                 \
+			alloc_mutex.unlock();                                                                  \
 			return rid;                                                                            \
 		} else {                                                                                   \
 			return server_name->m_type##_create(p1, p2);                                           \
@@ -150,7 +150,7 @@
 	virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) {                                     \
 		if (Thread::get_caller_id() != server_thread) {                                                \
 			RID rid;                                                                                   \
-			alloc_mutex->lock();                                                                       \
+			alloc_mutex.lock();                                                                        \
 			if (m_type##_id_pool.size() == 0) {                                                        \
 				int ret;                                                                               \
 				command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \
@@ -158,7 +158,7 @@
 			}                                                                                          \
 			rid = m_type##_id_pool.front()->get();                                                     \
 			m_type##_id_pool.pop_front();                                                              \
-			alloc_mutex->unlock();                                                                     \
+			alloc_mutex.unlock();                                                                      \
 			return rid;                                                                                \
 		} else {                                                                                       \
 			return server_name->m_type##_create(p1, p2, p3);                                           \
@@ -181,7 +181,7 @@
 	virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) {                              \
 		if (Thread::get_caller_id() != server_thread) {                                                    \
 			RID rid;                                                                                       \
-			alloc_mutex->lock();                                                                           \
+			alloc_mutex.lock();                                                                            \
 			if (m_type##_id_pool.size() == 0) {                                                            \
 				int ret;                                                                                   \
 				command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \
@@ -189,7 +189,7 @@
 			}                                                                                              \
 			rid = m_type##_id_pool.front()->get();                                                         \
 			m_type##_id_pool.pop_front();                                                                  \
-			alloc_mutex->unlock();                                                                         \
+			alloc_mutex.unlock();                                                                          \
 			return rid;                                                                                    \
 		} else {                                                                                           \
 			return server_name->m_type##_create(p1, p2, p3, p4);                                           \
@@ -213,7 +213,7 @@
 	virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) {                       \
 		if (Thread::get_caller_id() != server_thread) {                                                        \
 			RID rid;                                                                                           \
-			alloc_mutex->lock();                                                                               \
+			alloc_mutex.lock();                                                                                \
 			if (m_type##_id_pool.size() == 0) {                                                                \
 				int ret;                                                                                       \
 				command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \
@@ -221,7 +221,7 @@
 			}                                                                                                  \
 			rid = m_type##_id_pool.front()->get();                                                             \
 			m_type##_id_pool.pop_front();                                                                      \
-			alloc_mutex->unlock();                                                                             \
+			alloc_mutex.unlock();                                                                              \
 			return rid;                                                                                        \
 		} else {                                                                                               \
 			return server_name->m_type##_create(p1, p2, p3, p4, p5);                                           \

+ 6 - 15
servers/visual/visual_server_scene.cpp

@@ -2718,13 +2718,13 @@ void VisualServerScene::_gi_probe_bake_thread() {
 
 		Instance *to_bake = NULL;
 
-		probe_bake_mutex->lock();
+		probe_bake_mutex.lock();
 
 		if (!probe_bake_list.empty()) {
 			to_bake = probe_bake_list.front()->get();
 			probe_bake_list.pop_front();
 		}
-		probe_bake_mutex->unlock();
+		probe_bake_mutex.unlock();
 
 		if (!to_bake)
 			continue;
@@ -3263,15 +3263,9 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
 	}
 
 	//send back to main thread to update un little chunks
-	if (probe_bake_mutex) {
-		probe_bake_mutex->lock();
-	}
-
+	probe_bake_mutex.lock();
 	probe_data->dynamic.updating_stage = GI_UPDATE_STAGE_UPLOADING;
-
-	if (probe_bake_mutex) {
-		probe_bake_mutex->unlock();
-	}
+	probe_bake_mutex.unlock();
 }
 
 bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
@@ -3412,10 +3406,10 @@ void VisualServerScene::render_probes() {
 					if (_check_gi_probe(instance_probe) || force_lighting) { //send to lighting thread
 
 #ifndef NO_THREADS
-						probe_bake_mutex->lock();
+						probe_bake_mutex.lock();
 						probe->dynamic.updating_stage = GI_UPDATE_STAGE_LIGHTING;
 						probe_bake_list.push_back(instance_probe);
-						probe_bake_mutex->unlock();
+						probe_bake_mutex.unlock();
 						probe_bake_sem->post();
 
 #else
@@ -3690,7 +3684,6 @@ VisualServerScene::VisualServerScene() {
 
 #ifndef NO_THREADS
 	probe_bake_sem = Semaphore::create();
-	probe_bake_mutex = Mutex::create();
 	probe_bake_thread = Thread::create(_gi_probe_bake_threads, this);
 	probe_bake_thread_exit = false;
 #endif
@@ -3708,7 +3701,5 @@ VisualServerScene::~VisualServerScene() {
 	Thread::wait_to_finish(probe_bake_thread);
 	memdelete(probe_bake_thread);
 	memdelete(probe_bake_sem);
-	memdelete(probe_bake_mutex);
-
 #endif
 }

+ 1 - 1
servers/visual/visual_server_scene.h

@@ -594,7 +594,7 @@ public:
 	volatile bool probe_bake_thread_exit;
 	Thread *probe_bake_thread;
 	Semaphore *probe_bake_sem;
-	Mutex *probe_bake_mutex;
+	Mutex probe_bake_mutex;
 	List<Instance *> probe_bake_list;
 
 	bool _render_reflection_probe_step(Instance *p_instance, int p_step);

+ 0 - 2
servers/visual/visual_server_wrap_mt.cpp

@@ -180,7 +180,6 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_
 	thread = NULL;
 	draw_pending = 0;
 	draw_thread_up = false;
-	alloc_mutex = Mutex::create();
 	pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
 
 	if (!p_create_thread) {
@@ -193,6 +192,5 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_
 VisualServerWrapMT::~VisualServerWrapMT() {
 
 	memdelete(visual_server);
-	memdelete(alloc_mutex);
 	//finish();
 }

+ 1 - 1
servers/visual/visual_server_wrap_mt.h

@@ -57,7 +57,7 @@ class VisualServerWrapMT : public VisualServer {
 
 	void thread_exit();
 
-	Mutex *alloc_mutex;
+	Mutex alloc_mutex;
 
 	int pool_max_size;