From 18fbdbb456c07a56b358bea2e392765fbcbb3283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Wed, 26 Feb 2020 11:28:13 +0100 Subject: [PATCH] Reimplement Mutex with C++'s Main: - It's now implemented thanks to ``. No more platform-specific implementations. - `BinaryMutex` (non-recursive) is added, as an alternative for special cases. - Doesn't need allocation/deallocation anymore. It can live in the stack and be part of other classes. - Because of that, it's methods are now `const` and the inner mutex is `mutable` so it can be easily used in `const` contexts. - A no-op implementation is provided if `NO_THREADS` is defined. No more need to add `#ifdef NO_THREADS` just for this. - `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`. - Thread-safe utilities are therefore simpler now. Misc.: - `ScopedMutexLock` is dropped and replaced by `MutexLock`, because they were pretty much the same. - Every case of lock, do-something, unlock is replaced by `MutexLock` (complex cases where it's not straightfoward are kept as as explicit lock and unlock). - `ShaderRD` contained an `std::mutex`, which has been replaced by `Mutex`. --- core/bind/core_bind.cpp | 16 +- core/bind/core_bind.h | 5 +- core/command_queue_mt.cpp | 8 +- core/command_queue_mt.h | 2 +- core/io/file_access_network.cpp | 59 +++-- core/io/file_access_network.h | 6 +- core/io/ip.cpp | 42 ++-- core/io/resource_loader.cpp | 31 +-- core/io/resource_loader.h | 2 +- core/os/mutex.cpp | 32 +-- core/os/mutex.h | 73 ++++-- core/os/os.h | 2 - core/os/thread_dummy.cpp | 8 - core/os/thread_dummy.h | 13 -- core/os/thread_safe.cpp | 49 ---- core/os/thread_safe.h | 49 +--- core/register_core_types.cpp | 9 +- core/script_debugger_remote.cpp | 32 ++- core/script_debugger_remote.h | 2 +- core/string_name.cpp | 42 +--- core/string_name.h | 2 +- drivers/alsa/audio_driver_alsa.cpp | 15 +- drivers/alsa/audio_driver_alsa.h | 2 +- drivers/alsamidi/midi_driver_alsamidi.cpp | 13 +- drivers/alsamidi/midi_driver_alsamidi.h | 2 +- drivers/coreaudio/audio_driver_coreaudio.cpp | 18 +- drivers/coreaudio/audio_driver_coreaudio.h | 2 +- .../pulseaudio/audio_driver_pulseaudio.cpp | 14 +- drivers/pulseaudio/audio_driver_pulseaudio.h | 2 +- drivers/unix/mutex_posix.cpp | 73 ------ drivers/unix/mutex_posix.h | 61 ----- drivers/unix/os_unix.cpp | 3 - drivers/wasapi/audio_driver_wasapi.cpp | 13 +- drivers/wasapi/audio_driver_wasapi.h | 2 +- drivers/windows/mutex_windows.cpp | 101 --------- drivers/windows/mutex_windows.h | 63 ------ drivers/xaudio2/audio_driver_xaudio2.cpp | 12 +- drivers/xaudio2/audio_driver_xaudio2.h | 2 +- editor/editor_node.cpp | 19 +- editor/editor_node.h | 2 +- editor/editor_resource_preview.cpp | 137 ++++++------ editor/editor_resource_preview.h | 2 +- editor/fileserver/editor_file_server.cpp | 17 +- editor/fileserver/editor_file_server.h | 2 +- editor/import/resource_importer_texture.cpp | 101 ++++----- editor/import/resource_importer_texture.h | 2 +- .../gdnative/nativescript/nativescript.cpp | 61 +---- modules/gdnative/nativescript/nativescript.h | 12 +- .../pluginscript/pluginscript_language.cpp | 25 +-- .../pluginscript/pluginscript_language.h | 2 +- modules/gdnavigation/gd_navigation_server.cpp | 32 +-- modules/gdnavigation/gd_navigation_server.h | 5 +- modules/gdscript/gdscript.cpp | 167 ++++---------- modules/gdscript/gdscript.h | 2 +- modules/gdscript/gdscript_function.cpp | 19 +- modules/mono/csharp_script.cpp | 71 ++---- modules/mono/csharp_script.h | 10 +- modules/mono/mono_gd/gd_mono_utils.cpp | 4 +- modules/mono/utils/mutex_utils.h | 67 ------ modules/visual_script/visual_script.cpp | 26 +-- modules/visual_script/visual_script.h | 2 +- platform/android/audio_driver_jandroid.cpp | 13 +- platform/android/audio_driver_jandroid.h | 2 +- platform/android/audio_driver_opensl.cpp | 14 +- platform/android/audio_driver_opensl.h | 2 +- platform/android/export/export.cpp | 28 +-- platform/haiku/audio_driver_media_kit.cpp | 11 +- platform/haiku/audio_driver_media_kit.h | 2 +- platform/javascript/export/export.cpp | 27 ++- platform/uwp/os_uwp.cpp | 1 - platform/windows/os_windows.cpp | 2 - platform/x11/joypad_linux.cpp | 28 ++- platform/x11/joypad_linux.h | 2 +- scene/2d/canvas_item.cpp | 40 +--- scene/2d/canvas_item.h | 2 +- scene/2d/cpu_particles_2d.cpp | 167 ++++++-------- scene/2d/cpu_particles_2d.h | 2 +- scene/2d/navigation_polygon.cpp | 44 ++-- scene/2d/navigation_polygon.h | 4 +- scene/3d/cpu_particles.cpp | 209 ++++++++---------- scene/3d/cpu_particles.h | 2 +- scene/resources/dynamic_font.cpp | 59 ++--- scene/resources/dynamic_font.h | 2 +- scene/resources/material.cpp | 40 +--- scene/resources/material.h | 2 +- scene/resources/particles_material.cpp | 40 +--- scene/resources/particles_material.h | 2 +- servers/audio/audio_driver_dummy.cpp | 12 +- servers/audio/audio_driver_dummy.h | 2 +- servers/audio_server.cpp | 19 +- servers/audio_server.h | 2 +- .../physics_2d/physics_2d_server_wrap_mt.cpp | 2 - .../physics_2d/physics_2d_server_wrap_mt.h | 2 +- servers/server_wrap_mt_common.h | 18 +- servers/visual/rasterizer_rd/shader_rd.cpp | 12 +- servers/visual/rasterizer_rd/shader_rd.h | 4 +- servers/visual/visual_server_wrap_mt.cpp | 2 - servers/visual/visual_server_wrap_mt.h | 2 +- 98 files changed, 739 insertions(+), 1754 deletions(-) delete mode 100644 core/os/thread_safe.cpp delete mode 100644 drivers/unix/mutex_posix.cpp delete mode 100644 drivers/unix/mutex_posix.h delete mode 100644 drivers/windows/mutex_windows.cpp delete mode 100644 drivers/windows/mutex_windows.h delete mode 100644 modules/mono/utils/mutex_utils.h diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index c1cf061854..d9cc77feb3 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2583,17 +2583,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() { @@ -2603,16 +2603,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) { diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index ae569ea189..e68c40c9e4 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -609,7 +609,7 @@ public: class _Mutex : public Reference { GDCLASS(_Mutex, Reference); - Mutex *mutex; + Mutex mutex; static void _bind_methods(); @@ -617,9 +617,6 @@ public: void lock(); Error try_lock(); void unlock(); - - _Mutex(); - ~_Mutex(); }; class _Semaphore : public Reference { diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp index 861ca8d1d3..b88f773ed8 100644 --- a/core/command_queue_mt.cpp +++ b/core/command_queue_mt.cpp @@ -34,14 +34,12 @@ void CommandQueueMT::lock() { - if (mutex) - mutex->lock(); + mutex.lock(); } void CommandQueueMT::unlock() { - if (mutex) - mutex->unlock(); + mutex.unlock(); } void CommandQueueMT::wait_for_flush() { @@ -106,7 +104,6 @@ CommandQueueMT::CommandQueueMT(bool p_sync) { read_ptr = 0; write_ptr = 0; dealloc_ptr = 0; - mutex = Mutex::create(); command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE); for (int i = 0; i < SYNC_SEMAPHORES; i++) { @@ -124,7 +121,6 @@ CommandQueueMT::~CommandQueueMT() { if (sync) memdelete(sync); - memdelete(mutex); for (int i = 0; i < SYNC_SEMAPHORES; i++) { memdelete(sync_sems[i].sem); diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index 2b6e0201f0..7407557e7e 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -341,7 +341,7 @@ class CommandQueueMT { uint32_t write_ptr; uint32_t dealloc_ptr; SyncSemaphore sync_sems[SYNC_SEMAPHORES]; - Mutex *mutex; + Mutex mutex; SemaphoreOld *sync; template diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 202eb89dbd..7f1eb6fd90 100644 --- a/core/io/file_access_network.cpp +++ b/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,15 +97,16 @@ void FileAccessNetworkClient::_thread_func() { lock_mutex(); DEBUG_PRINT("MUTEX PASS"); - blockrequest_mutex->lock(); - while (block_requests.size()) { - put_32(block_requests.front()->get().id); - put_32(FileAccessNetwork::COMMAND_READ_BLOCK); - put_64(block_requests.front()->get().offset); - put_32(block_requests.front()->get().size); - block_requests.pop_front(); + { + MutexLock lock(blockrequest_mutex); + while (block_requests.size()) { + put_32(block_requests.front()->get().id); + put_32(FileAccessNetwork::COMMAND_READ_BLOCK); + put_64(block_requests.front()->get().offset); + put_32(block_requests.front()->get().size); + block_requests.pop_front(); + } } - blockrequest_mutex->unlock(); DEBUG_PRINT("THREAD ITER"); @@ -225,8 +226,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 +243,6 @@ FileAccessNetworkClient::~FileAccessNetworkClient() { memdelete(thread); } - memdelete(blockrequest_mutex); - memdelete(mutex); memdelete(sem); } @@ -259,10 +256,11 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector &p_block) ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size))); } - buffer_mutex->lock(); - pages.write[page].buffer = p_block; - pages.write[page].queued = false; - buffer_mutex->unlock(); + { + MutexLock lock(buffer_mutex); + pages.write[page].buffer = p_block; + pages.write[page].queued = false; + } if (waiting_on_page == page) { waiting_on_page = -1; @@ -384,15 +382,16 @@ void FileAccessNetwork::_queue_page(int p_page) const { if (pages[p_page].buffer.empty() && !pages[p_page].queued) { FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; + { + MutexLock lock(nc->blockrequest_mutex); - 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(); + 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; + } DEBUG_PRINT("QUEUE PAGE POST"); nc->sem->post(); DEBUG_PRINT("queued " + itos(p_page)); @@ -418,14 +417,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 +435,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 +523,6 @@ FileAccessNetwork::FileAccessNetwork() { pos = 0; sem = SemaphoreOld::create(); page_sem = SemaphoreOld::create(); - buffer_mutex = Mutex::create(); FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; nc->lock_mutex(); id = nc->last_id++; @@ -542,7 +540,6 @@ FileAccessNetwork::~FileAccessNetwork() { close(); memdelete(sem); memdelete(page_sem); - memdelete(buffer_mutex); FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; nc->lock_mutex(); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index f329abf7c5..38d9b8e8a6 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -52,8 +52,8 @@ class FileAccessNetworkClient { SemaphoreOld *sem; Thread *thread; bool quit; - Mutex *mutex; - Mutex *blockrequest_mutex; + Mutex mutex; + Mutex blockrequest_mutex; Map accesses; Ref client; int last_id; @@ -87,7 +87,7 @@ class FileAccessNetwork : public FileAccess { SemaphoreOld *sem; SemaphoreOld *page_sem; - Mutex *buffer_mutex; + Mutex buffer_mutex; bool opened; size_t total_size; mutable size_t pos; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 7d18117711..af534e4bb7 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -70,7 +70,7 @@ struct _IP_ResolverPrivate { return IP::RESOLVER_INVALID_ID; } - Mutex *mutex; + Mutex mutex; SemaphoreOld *sem; Thread *thread; @@ -100,9 +100,8 @@ struct _IP_ResolverPrivate { ipr->sem->wait(); - ipr->mutex->lock(); + MutexLock lock(ipr->mutex); ipr->resolve_queues(); - ipr->mutex->unlock(); } } @@ -115,30 +114,27 @@ struct _IP_ResolverPrivate { IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); 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(); return res; } IP_Address res = _resolve_hostname(p_hostname, p_type); resolver->cache[key] = res; - resolver->mutex->unlock(); return res; } IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) { - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); ResolverID id = resolver->find_empty_id(); if (id == RESOLVER_INVALID_ID) { WARN_PRINT("Out of resolver queries"); - resolver->mutex->unlock(); return id; } @@ -157,7 +153,6 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ resolver->resolve_queues(); } - resolver->mutex->unlock(); return id; } @@ -165,50 +160,43 @@ 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(); + MutexLock lock(resolver->mutex); + 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(); - return res; + return resolver->queue[p_id].status; } 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(); + MutexLock lock(resolver->mutex); if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) { ERR_PRINT("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(); - return res; + return resolver->queue[p_id].response; } void IP::erase_resolve_item(ResolverID p_id) { ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES); - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE; - - resolver->mutex->unlock(); } void IP::clear_cache(const String &p_hostname) { - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); if (p_hostname.empty()) { resolver->cache.clear(); @@ -218,8 +206,6 @@ void IP::clear_cache(const String &p_hostname) { resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_IPV6)); resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY)); } - - resolver->mutex->unlock(); } Array IP::_get_local_addresses() const { @@ -315,7 +301,6 @@ IP::IP() { singleton = this; resolver = memnew(_IP_ResolverPrivate); resolver->sem = NULL; - resolver->mutex = Mutex::create(); #ifndef NO_THREADS @@ -349,6 +334,5 @@ IP::~IP() { #endif - memdelete(resolver->mutex); memdelete(resolver); } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 39bbebefa6..b43cd7f1a2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -288,9 +288,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(); - } + MutexLock lock(loading_map_mutex); LoadingMapKey key; key.path = p_path; @@ -303,43 +301,27 @@ bool ResourceLoader::_add_to_loading_map(const String &p_path) { success = true; } - if (loading_map_mutex) { - loading_map_mutex->unlock(); - } - return success; } void ResourceLoader::_remove_from_loading_map(const String &p_path) { - if (loading_map_mutex) { - loading_map_mutex->lock(); - } + MutexLock lock(loading_map_mutex); LoadingMapKey key; key.path = p_path; key.thread = Thread::get_caller_id(); loading_map.erase(key); - - if (loading_map_mutex) { - 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(); - } + MutexLock lock(loading_map_mutex); LoadingMapKey key; key.path = p_path; key.thread = p_thread; loading_map.erase(key); - - if (loading_map_mutex) { - loading_map_mutex->unlock(); - } } RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { @@ -1002,13 +984,10 @@ void ResourceLoader::remove_custom_loaders() { } } -Mutex *ResourceLoader::loading_map_mutex = NULL; +Mutex ResourceLoader::loading_map_mutex; HashMap ResourceLoader::loading_map; void ResourceLoader::initialize() { -#ifndef NO_THREADS - loading_map_mutex = Mutex::create(); -#endif } void ResourceLoader::finalize() { @@ -1018,8 +997,6 @@ void ResourceLoader::finalize() { ERR_PRINT("Exited while resource is being loaded: " + K->path); } loading_map.clear(); - memdelete(loading_map_mutex); - loading_map_mutex = NULL; #endif } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 4e83427fae..172f8e979b 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -120,7 +120,7 @@ class ResourceLoader { static ResourceLoadedCallback _loaded_callback; static Ref _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 { diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp index f099b4319a..74c308f646 100644 --- a/core/os/mutex.cpp +++ b/core/os/mutex.cpp @@ -30,31 +30,17 @@ #include "mutex.h" -#include "core/error_macros.h" - -#include - -Mutex *(*Mutex::create_func)(bool) = 0; - -Mutex *Mutex::create(bool p_recursive) { - - ERR_FAIL_COND_V(!create_func, 0); - - return create_func(p_recursive); -} - -Mutex::~Mutex() { -} - -Mutex *_global_mutex = NULL; +static Mutex _global_mutex; void _global_lock() { - - if (_global_mutex) - _global_mutex->lock(); + _global_mutex.lock(); } + void _global_unlock() { - - if (_global_mutex) - _global_mutex->unlock(); + _global_mutex.unlock(); } + +template class MutexImpl; +template class MutexImpl; +template class MutexLock >; +template class MutexLock >; diff --git a/core/os/mutex.h b/core/os/mutex.h index db82eb64f5..6cf8ee7c40 100644 --- a/core/os/mutex.h +++ b/core/os/mutex.h @@ -32,42 +32,69 @@ #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 + +template +class MutexImpl { + mutable StdMutexT mutex; 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; + } }; +template class MutexLock { - - Mutex *mutex; + const MutexT &mutex; public: - MutexLock(Mutex *p_mutex) { - mutex = p_mutex; - if (mutex) mutex->lock(); + _ALWAYS_INLINE_ explicit MutexLock(const MutexT &p_mutex) : + mutex(p_mutex) { + mutex.lock(); } - ~MutexLock() { - if (mutex) mutex->unlock(); + + _ALWAYS_INLINE_ ~MutexLock() { + mutex.unlock(); } }; +#else + +template +class MutexImpl { +public: + _ALWAYS_INLINE_ void lock() const {} + _ALWAYS_INLINE_ void unlock() const {} + _ALWAYS_INLINE_ Error try_lock() const { return OK; } +}; + +template +class MutexLock { +public: + explicit MutexLock(const MutexT &p_mutex) {} +}; + +#endif // !NO_THREADS + +using Mutex = MutexImpl; // Recursive, for general use +using BinaryMutex = MutexImpl; // Non-recursive, handle with care + +extern template class MutexImpl; +extern template class MutexImpl; +extern template class MutexLock >; +extern template class MutexLock >; + #endif diff --git a/core/os/os.h b/core/os/os.h index 77391c3a8b..1d3619b1e6 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -41,8 +41,6 @@ #include -class Mutex; - class OS { static OS *singleton; diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp index 916aeeda30..097c90c1fb 100644 --- a/core/os/thread_dummy.cpp +++ b/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; -}; - SemaphoreOld *SemaphoreDummy::create() { return memnew(SemaphoreDummy); }; diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h index 9329cdaa32..c0976ec299 100644 --- a/core/os/thread_dummy.h +++ b/core/os/thread_dummy.h @@ -31,7 +31,6 @@ #ifndef THREAD_DUMMY_H #define THREAD_DUMMY_H -#include "core/os/mutex.h" #include "core/os/rw_lock.h" #include "core/os/semaphore.h" #include "core/os/thread.h" @@ -46,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 SemaphoreOld { static SemaphoreOld *create(); diff --git a/core/os/thread_safe.cpp b/core/os/thread_safe.cpp deleted file mode 100644 index d8d783ae16..0000000000 --- a/core/os/thread_safe.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************/ -/* thread_safe.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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); -} diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h index a4238a9225..0221edf491 100644 --- a/core/os/thread_safe.h +++ b/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 diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index bb017f43e5..ac60061c67 100644 --- a/core/register_core_types.cpp +++ b/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(); @@ -105,8 +105,6 @@ void register_core_types() { ObjectDB::setup(); ResourceCache::setup(); - _global_mutex = Mutex::create(); - StringName::setup(); ResourceLoader::initialize(); @@ -319,9 +317,4 @@ void unregister_core_types() { ResourceCache::clear(); CoreStringNames::free(); StringName::cleanup(); - - if (_global_mutex) { - memdelete(_global_mutex); - _global_mutex = NULL; //still needed at a few places - }; } diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index fdb6135edd..67375da6e2 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -601,7 +601,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue, void ScriptDebuggerRemote::_get_output() { - mutex->lock(); + MutexLock lock(mutex); + if (output_strings.size()) { locking = true; @@ -666,7 +667,6 @@ void ScriptDebuggerRemote::_get_output() { errors.pop_front(); locking = false; } - mutex->unlock(); } void ScriptDebuggerRemote::line_poll() { @@ -914,7 +914,8 @@ void ScriptDebuggerRemote::_send_network_bandwidth_usage() { void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) { - mutex->lock(); + MutexLock lock(mutex); + if (!locking && is_peer_connected()) { if (messages.size() >= max_messages_per_frame) { @@ -926,7 +927,6 @@ void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_ messages.push_back(msg); } } - 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 &p_stack_info) { @@ -972,7 +972,7 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file err_count++; } - mutex->lock(); + MutexLock lock(mutex); if (!locking && is_peer_connected()) { @@ -990,8 +990,6 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file } } } - - mutex->unlock(); } void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) { @@ -1020,19 +1018,21 @@ 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(); - if (!sdr->locking && sdr->is_peer_connected()) { + { + MutexLock lock(sdr->mutex); - if (overflowed) - s += "[...]"; + if (!sdr->locking && sdr->is_peer_connected()) { - sdr->output_strings.push_back(s); + if (overflowed) + s += "[...]"; - if (overflowed) { - sdr->output_strings.push_back("[output overflow, print less text!]"); + sdr->output_strings.push_back(s); + + if (overflowed) { + sdr->output_strings.push_back("[output overflow, print less text!]"); + } } } - sdr->mutex->unlock(); } void ScriptDebuggerRemote::request_quit() { @@ -1106,7 +1106,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")), @@ -1141,5 +1140,4 @@ ScriptDebuggerRemote::~ScriptDebuggerRemote() { remove_print_handler(&phl); remove_error_handler(&eh); - memdelete(mutex); } diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index 682da1d276..b7a309b2f9 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -230,7 +230,7 @@ protected: uint64_t last_net_bandwidth_time; Object *performance; bool requested_quit; - Mutex *mutex; + Mutex mutex; List output_strings; List messages; diff --git a/core/string_name.cpp b/core/string_name.cpp index 6f7b10c5fe..dd6868f6d2 100644 --- a/core/string_name.cpp +++ b/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(); + MutexLock lock(StringName::lock); int lost_strings = 0; for (int i = 0; i < STRING_TABLE_LEN; i++) { @@ -87,9 +85,6 @@ void StringName::cleanup() { if (lost_strings) { print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); } - lock->unlock(); - - memdelete(lock); } void StringName::unref() { @@ -98,7 +93,7 @@ void StringName::unref() { if (_data && _data->refcount.unref()) { - lock->lock(); + MutexLock lock(StringName::lock); if (_data->prev) { _data->prev->next = _data->next; @@ -113,7 +108,6 @@ void StringName::unref() { _data->next->prev = _data->prev; } memdelete(_data); - lock->unlock(); } _data = NULL; @@ -184,7 +178,7 @@ StringName::StringName(const char *p_name) { if (!p_name || p_name[0] == 0) return; //empty, ignore - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_name); @@ -203,7 +197,6 @@ StringName::StringName(const char *p_name) { if (_data) { if (_data->refcount.ref()) { // exists - lock->unlock(); return; } } @@ -219,8 +212,6 @@ StringName::StringName(const char *p_name) { if (_table[idx]) _table[idx]->prev = _data; _table[idx] = _data; - - lock->unlock(); } StringName::StringName(const StaticCString &p_static_string) { @@ -231,7 +222,7 @@ StringName::StringName(const StaticCString &p_static_string) { ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_static_string.ptr); @@ -250,7 +241,6 @@ StringName::StringName(const StaticCString &p_static_string) { if (_data) { if (_data->refcount.ref()) { // exists - lock->unlock(); return; } } @@ -266,8 +256,6 @@ StringName::StringName(const StaticCString &p_static_string) { if (_table[idx]) _table[idx]->prev = _data; _table[idx] = _data; - - lock->unlock(); } StringName::StringName(const String &p_name) { @@ -279,10 +267,9 @@ StringName::StringName(const String &p_name) { if (p_name == String()) return; - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = p_name.hash(); - uint32_t idx = hash & STRING_TABLE_MASK; _data = _table[idx]; @@ -297,7 +284,6 @@ StringName::StringName(const String &p_name) { if (_data) { if (_data->refcount.ref()) { // exists - lock->unlock(); return; } } @@ -313,8 +299,6 @@ StringName::StringName(const String &p_name) { if (_table[idx]) _table[idx]->prev = _data; _table[idx] = _data; - - lock->unlock(); } StringName StringName::search(const char *p_name) { @@ -325,10 +309,9 @@ StringName StringName::search(const char *p_name) { if (!p_name[0]) return StringName(); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_name); - uint32_t idx = hash & STRING_TABLE_MASK; _Data *_data = _table[idx]; @@ -342,12 +325,9 @@ StringName StringName::search(const char *p_name) { } if (_data && _data->refcount.ref()) { - lock->unlock(); - return StringName(_data); } - lock->unlock(); return StringName(); //does not exist } @@ -359,7 +339,7 @@ StringName StringName::search(const CharType *p_name) { if (!p_name[0]) return StringName(); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_name); @@ -376,18 +356,16 @@ StringName StringName::search(const CharType *p_name) { } if (_data && _data->refcount.ref()) { - lock->unlock(); return StringName(_data); } - lock->unlock(); return StringName(); //does not exist } StringName StringName::search(const String &p_name) { ERR_FAIL_COND_V(p_name == "", StringName()); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = p_name.hash(); @@ -404,11 +382,9 @@ StringName StringName::search(const String &p_name) { } if (_data && _data->refcount.ref()) { - lock->unlock(); return StringName(_data); } - lock->unlock(); return StringName(); //does not exist } diff --git a/core/string_name.h b/core/string_name.h index 4096b8f650..0cf2f126aa 100644 --- a/core/string_name.h +++ b/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; diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index fe6cd091b7..400ce31bf7 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -154,7 +154,6 @@ Error AudioDriverALSA::init() { Error err = init_device(); if (err == OK) { - mutex = Mutex::create(); thread = Thread::create(AudioDriverALSA::thread_func, this); } @@ -299,16 +298,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() { @@ -327,11 +326,6 @@ void AudioDriverALSA::finish() { memdelete(thread); thread = NULL; - - if (mutex) { - memdelete(mutex); - mutex = NULL; - } } finish_device(); @@ -339,7 +333,6 @@ void AudioDriverALSA::finish() { AudioDriverALSA::AudioDriverALSA() : thread(NULL), - mutex(NULL), pcm_handle(NULL), device_name("Default"), new_device("Default") { diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index fb793df6cd..a8caf0fbae 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -40,7 +40,7 @@ class AudioDriverALSA : public AudioDriver { Thread *thread; - Mutex *mutex; + Mutex mutex; snd_pcm_t *pcm_handle; diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index 670d7e0a4a..0cecf1de3e 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/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(); } PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() { @@ -210,7 +202,6 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() { MIDIDriverALSAMidi::MIDIDriverALSAMidi() { - mutex = NULL; thread = NULL; exit_thread = false; diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h index 9900d90553..6797c7c138 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -44,7 +44,7 @@ class MIDIDriverALSAMidi : public MIDIDriver { Thread *thread; - Mutex *mutex; + Mutex mutex; Vector connected_inputs; diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index d8229f7bf2..1e95bcf5d9 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/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), diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h index 05aa759078..fb9473e230 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.h +++ b/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; diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index df9303fbec..ee9278fb8f 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -291,7 +291,6 @@ Error AudioDriverPulseAudio::init() { Error err = init_device(); if (err == OK) { - mutex = Mutex::create(); thread = Thread::create(AudioDriverPulseAudio::thread_func, this); } @@ -597,16 +596,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() { @@ -640,10 +639,6 @@ void AudioDriverPulseAudio::finish() { } memdelete(thread); - if (mutex) { - memdelete(mutex); - mutex = NULL; - } thread = NULL; } @@ -800,7 +795,6 @@ String AudioDriverPulseAudio::capture_get_device() { AudioDriverPulseAudio::AudioDriverPulseAudio() : thread(NULL), - mutex(NULL), pa_ml(NULL), pa_ctx(NULL), pa_str(NULL), diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 15948fa763..1ece332a8a 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/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; diff --git a/drivers/unix/mutex_posix.cpp b/drivers/unix/mutex_posix.cpp deleted file mode 100644 index a9fc12fb06..0000000000 --- a/drivers/unix/mutex_posix.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************/ -/* mutex_posix.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 diff --git a/drivers/unix/mutex_posix.h b/drivers/unix/mutex_posix.h deleted file mode 100644 index bd67106836..0000000000 --- a/drivers/unix/mutex_posix.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ -/* mutex_posix.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 - -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 diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 2d8d37b2f1..1d94b9618d 100644 --- a/drivers/unix/os_unix.cpp +++ b/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/rw_lock_posix.h" #include "drivers/unix/semaphore_posix.h" @@ -123,14 +122,12 @@ void OS_Unix::initialize_core() { #ifdef NO_THREADS ThreadDummy::make_default(); SemaphoreDummy::make_default(); - MutexDummy::make_default(); RWLockDummy::make_default(); #else ThreadPosix::make_default(); #if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED) SemaphorePosix::make_default(); #endif - MutexPosix::make_default(); RWLockPosix::make_default(); #endif FileAccess::make_default(FileAccess::ACCESS_RESOURCES); diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 8aa6fb96c9..fa78771993 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/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(); diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index ebceedd431..3ea61c6010 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/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 samples_in; diff --git a/drivers/windows/mutex_windows.cpp b/drivers/windows/mutex_windows.cpp deleted file mode 100644 index 1f14adb48f..0000000000 --- a/drivers/windows/mutex_windows.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* mutex_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 diff --git a/drivers/windows/mutex_windows.h b/drivers/windows/mutex_windows.h deleted file mode 100644 index 28b97540b7..0000000000 --- a/drivers/windows/mutex_windows.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* mutex_windows.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 - -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 diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 85e505009b..9c7cb4f0f3 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/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++) { diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h index 98950851d0..108891a288 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.h +++ b/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]; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b632e7594c..9624b3ee56 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5554,7 +5554,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; @@ -5574,7 +5574,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; @@ -5585,20 +5584,20 @@ 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(); - 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(); + { + MutexLock lock(eta.execute_output_mutex); + 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(); 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) { diff --git a/editor/editor_node.h b/editor/editor_node.h index a982b9d85f..0b3de5c142 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -107,7 +107,7 @@ public: List args; String output; Thread *execute_output_thread; - Mutex *execute_output_mutex; + Mutex execute_output_mutex; int exitcode; volatile bool done; }; diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index c0f58c9aae..40482dc367 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -109,30 +109,29 @@ void EditorResourcePreview::_thread_func(void *ud) { void EditorResourcePreview::_preview_ready(const String &p_str, const Ref &p_texture, const Ref &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) { - preview_mutex->lock(); - + MutexLock lock(preview_mutex); String path = p_str; - uint32_t hash = 0; - uint64_t modified_time = 0; + { + uint32_t hash = 0; + uint64_t modified_time = 0; - if (p_str.begins_with("ID:")) { - hash = uint32_t(p_str.get_slicec(':', 2).to_int64()); - path = "ID:" + p_str.get_slicec(':', 1); - } else { - modified_time = FileAccess::get_modified_time(path); + if (p_str.begins_with("ID:")) { + hash = uint32_t(p_str.get_slicec(':', 2).to_int64()); + path = "ID:" + p_str.get_slicec(':', 1); + } else { + modified_time = FileAccess::get_modified_time(path); + } + + Item item; + item.order = order++; + item.preview = p_texture; + item.small_preview = p_small_texture; + item.last_hash = hash; + item.modified_time = modified_time; + + cache[path] = item; } - Item item; - item.order = order++; - item.preview = p_texture; - item.small_preview = p_small_texture; - item.last_hash = hash; - item.modified_time = modified_time; - - cache[path] = item; - - preview_mutex->unlock(); - MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_small_texture, p_ud); } @@ -219,7 +218,7 @@ void EditorResourcePreview::_thread() { while (!exit) { preview_sem->wait(); - preview_mutex->lock(); + preview_mutex.lock(); if (queue.size()) { @@ -235,10 +234,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 texture; Ref small_texture; @@ -345,7 +344,7 @@ void EditorResourcePreview::_thread() { } } else { - preview_mutex->unlock(); + preview_mutex.unlock(); } } exited = true; @@ -356,51 +355,54 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref &p ERR_FAIL_NULL(p_receiver); ERR_FAIL_COND(!p_res.is_valid()); - preview_mutex->lock(); + { + MutexLock lock(preview_mutex); - String path_id = "ID:" + itos(p_res->get_instance_id()); + String path_id = "ID:" + itos(p_res->get_instance_id()); - if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) { + if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) { - 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(); - return; + 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(); + return; + } + + cache.erase(path_id); //erase if exists, since it will be regen + + QueueItem item; + item.function = p_receiver_func; + item.id = p_receiver->get_instance_id(); + item.resource = p_res; + item.path = path_id; + item.userdata = p_userdata; + + queue.push_back(item); } - - cache.erase(path_id); //erase if exists, since it will be regen - - QueueItem item; - item.function = p_receiver_func; - item.id = p_receiver->get_instance_id(); - item.resource = p_res; - item.path = path_id; - item.userdata = p_userdata; - - queue.push_back(item); - 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(); - 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(); - return; + { + MutexLock lock(preview_mutex); + + 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(); + return; + } + + QueueItem item; + item.function = p_receiver_func; + item.id = p_receiver->get_instance_id(); + item.path = p_path; + item.userdata = p_userdata; + + queue.push_back(item); } - - QueueItem item; - item.function = p_receiver_func; - item.id = p_receiver->get_instance_id(); - item.path = p_path; - item.userdata = p_userdata; - - queue.push_back(item); - preview_mutex->unlock(); preview_sem->post(); } @@ -434,20 +436,19 @@ void EditorResourcePreview::_bind_methods() { void EditorResourcePreview::check_for_invalidation(const String &p_path) { - preview_mutex->lock(); - + MutexLock lock(preview_mutex); bool call_invalidated = false; - if (cache.has(p_path)) { + { + if (cache.has(p_path)) { - uint64_t modified_time = FileAccess::get_modified_time(p_path); - if (modified_time != cache[p_path].modified_time) { - cache.erase(p_path); - call_invalidated = true; + uint64_t modified_time = FileAccess::get_modified_time(p_path); + if (modified_time != cache[p_path].modified_time) { + cache.erase(p_path); + call_invalidated = true; + } } } - preview_mutex->unlock(); - if (call_invalidated) { //do outside mutex call_deferred("emit_signal", "preview_invalidated", p_path); } @@ -475,7 +476,6 @@ void EditorResourcePreview::stop() { EditorResourcePreview::EditorResourcePreview() { thread = NULL; singleton = this; - preview_mutex = Mutex::create(); preview_sem = SemaphoreOld::create(); order = 0; exit = false; @@ -485,6 +485,5 @@ EditorResourcePreview::EditorResourcePreview() { EditorResourcePreview::~EditorResourcePreview() { stop(); - memdelete(preview_mutex); memdelete(preview_sem); } diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 0a89154243..ae347c0469 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -70,7 +70,7 @@ class EditorResourcePreview : public Node { List queue; - Mutex *preview_mutex; + Mutex preview_mutex; SemaphoreOld *preview_sem; Thread *thread; volatile bool exit; diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index af7eb0c4c7..fb44c145b2 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -42,9 +42,10 @@ void EditorFileServer::_close_client(ClientData *cd) { cd->connection->disconnect_from_host(); - cd->efs->wait_mutex->lock(); - cd->efs->to_wait.insert(cd->thread); - cd->efs->wait_mutex->unlock(); + { + MutexLock lock(cd->efs->wait_mutex); + cd->efs->to_wait.insert(cd->thread); + } while (cd->files.size()) { memdelete(cd->files.front()->get()); cd->files.erase(cd->files.front()); @@ -295,16 +296,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 +332,6 @@ void EditorFileServer::stop() { EditorFileServer::EditorFileServer() { server.instance(); - wait_mutex = Mutex::create(); quit = false; active = false; cmd = CMD_NONE; @@ -346,5 +346,4 @@ EditorFileServer::~EditorFileServer() { quit = true; Thread::wait_to_finish(thread); memdelete(thread); - memdelete(wait_mutex); } diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index 4ce4c0cda6..cc3cb44566 100644 --- a/editor/fileserver/editor_file_server.h +++ b/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; diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 3254b32dae..92ecda8508 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -38,7 +38,8 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref &p_tex, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_channel) { - singleton->mutex->lock(); + MutexLock lock(singleton->mutex); + StringName path = p_tex->get_path(); if (!singleton->make_flags.has(path)) { @@ -48,13 +49,12 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Refmake_flags[path].flags |= MAKE_ROUGHNESS_FLAG; singleton->make_flags[path].channel_for_roughness = p_channel; singleton->make_flags[path].normal_path_for_roughness = p_normal_path; - - singleton->mutex->unlock(); } void ResourceImporterTexture::_texture_reimport_3d(const Ref &p_tex) { - singleton->mutex->lock(); + MutexLock lock(singleton->mutex); + StringName path = p_tex->get_path(); if (!singleton->make_flags.has(path)) { @@ -62,13 +62,12 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref &p_t } singleton->make_flags[path].flags |= MAKE_3D_FLAG; - - singleton->mutex->unlock(); } void ResourceImporterTexture::_texture_reimport_normal(const Ref &p_tex) { - singleton->mutex->lock(); + MutexLock lock(singleton->mutex); + StringName path = p_tex->get_path(); if (!singleton->make_flags.has(path)) { @@ -76,8 +75,6 @@ void ResourceImporterTexture::_texture_reimport_normal(const Ref } singleton->make_flags[path].flags |= MAKE_NORMAL_FLAG; - - singleton->mutex->unlock(); } void ResourceImporterTexture::update_imports() { @@ -85,58 +82,57 @@ void ResourceImporterTexture::update_imports() { if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) { return; // do nothing for now } - mutex->lock(); - - if (make_flags.empty()) { - mutex->unlock(); - return; - } + MutexLock lock(mutex); Vector to_reimport; - for (Map::Element *E = make_flags.front(); E; E = E->next()) { - - Ref cf; - cf.instance(); - String src_path = String(E->key()) + ".import"; - - Error err = cf->load(src_path); - ERR_CONTINUE(err != OK); - - bool changed = false; - - if (E->get().flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { - cf->set_value("params", "compress/normal_map", 1); - changed = true; + { + if (make_flags.empty()) { + return; } - if (E->get().flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) { - cf->set_value("params", "roughness/mode", E->get().channel_for_roughness + 2); - cf->set_value("params", "roughness/src_normal", E->get().normal_path_for_roughness); - changed = true; - } + for (Map::Element *E = make_flags.front(); E; E = E->next()) { - if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { - int compress_to = cf->get_value("params", "detect_3d/compress_to"); - cf->set_value("params", "detect_3d/compress_to", 0); - if (compress_to == 1) { - cf->set_value("params", "compress/mode", COMPRESS_VRAM_COMPRESSED); - } else if (compress_to == 2) { - cf->set_value("params", "compress/mode", COMPRESS_BASIS_UNIVERSAL); + Ref cf; + cf.instance(); + String src_path = String(E->key()) + ".import"; + + Error err = cf->load(src_path); + ERR_CONTINUE(err != OK); + + bool changed = false; + + if (E->get().flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { + cf->set_value("params", "compress/normal_map", 1); + changed = true; + } + + if (E->get().flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) { + cf->set_value("params", "roughness/mode", E->get().channel_for_roughness + 2); + cf->set_value("params", "roughness/src_normal", E->get().normal_path_for_roughness); + changed = true; + } + + if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { + int compress_to = cf->get_value("params", "detect_3d/compress_to"); + cf->set_value("params", "detect_3d/compress_to", 0); + if (compress_to == 1) { + cf->set_value("params", "compress/mode", COMPRESS_VRAM_COMPRESSED); + } else if (compress_to == 2) { + cf->set_value("params", "compress/mode", COMPRESS_BASIS_UNIVERSAL); + } + cf->set_value("params", "mipmaps/generate", true); + changed = true; + } + + if (changed) { + cf->save(src_path); + to_reimport.push_back(E->key()); } - cf->set_value("params", "mipmaps/generate", true); - changed = true; } - if (changed) { - cf->save(src_path); - to_reimport.push_back(E->key()); - } + make_flags.clear(); } - make_flags.clear(); - - mutex->unlock(); - if (to_reimport.size()) { EditorFileSystem::get_singleton()->reimport_files(to_reimport); } @@ -642,10 +638,7 @@ ResourceImporterTexture::ResourceImporterTexture() { StreamTexture::request_3d_callback = _texture_reimport_3d; StreamTexture::request_roughness_callback = _texture_reimport_roughness; StreamTexture::request_normal_callback = _texture_reimport_normal; - mutex = Mutex::create(); } ResourceImporterTexture::~ResourceImporterTexture() { - - memdelete(mutex); } diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 19d5498b4a..ed0fe1be89 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -58,7 +58,7 @@ protected: MAKE_NORMAL_FLAG = 4 }; - Mutex *mutex; + Mutex mutex; struct MakeInfo { int flags; diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 8240ae2f83..0ec6ad71d9 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -222,15 +222,11 @@ 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 + { + MutexLock lock(owners_lock); - instance_owners.insert(p_this); - -#ifndef NO_THREADS - owners_lock->unlock(); -#endif + instance_owners.insert(p_this); + } return nsi; } @@ -782,17 +778,10 @@ NativeScript::NativeScript() { library = Ref(); 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() @@ -1140,16 +1129,9 @@ NativeScriptInstance::~NativeScriptInstance() { script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata); if (owner) { - -#ifndef NO_THREADS - script->owners_lock->lock(); -#endif + MutexLock lock(script->owners_lock); script->instance_owners.erase(owner); - -#ifndef NO_THREADS - script->owners_lock->unlock(); -#endif } } @@ -1246,7 +1228,6 @@ NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; #ifndef NO_THREADS has_objects_to_register = false; - mutex = Mutex::create(); #endif #ifdef DEBUG_ENABLED @@ -1283,10 +1264,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 { @@ -1413,9 +1390,7 @@ void NativeScriptLanguage::get_public_constants(List > *p_ void NativeScriptLanguage::profiling_start() { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif profile_data.clear(); profiling = true; @@ -1424,9 +1399,7 @@ void NativeScriptLanguage::profiling_start() { void NativeScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif profiling = false; #endif @@ -1434,9 +1407,8 @@ void NativeScriptLanguage::profiling_stop() { int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + int current = 0; for (Map::Element *d = profile_data.front(); d; d = d->next()) { @@ -1458,9 +1430,8 @@ int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_a int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + int current = 0; for (Map::Element *d = profile_data.front(); d; d = d->next()) { @@ -1484,9 +1455,7 @@ int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif Map::Element *d = profile_data.find(p_signature); if (d) { @@ -1705,9 +1674,8 @@ void NativeScriptLanguage::defer_init_library(Ref lib, NativeSc #endif void NativeScriptLanguage::init_library(const Ref &lib) { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + // See if this library was "registered" already. const String &lib_path = lib->get_current_library_path(); ERR_FAIL_COND_MSG(lib_path.length() == 0, lib->get_name() + " does not have a library for the current platform."); @@ -1743,16 +1711,14 @@ void NativeScriptLanguage::init_library(const Ref &lib) { } void NativeScriptLanguage::register_script(NativeScript *script) { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + library_script_users[script->lib_path].insert(script); } void NativeScriptLanguage::unregister_script(NativeScript *script) { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + Map >::Element *S = library_script_users.find(script->lib_path); if (S) { S->get().erase(script); @@ -1803,9 +1769,7 @@ void NativeScriptLanguage::frame() { #ifdef DEBUG_ENABLED { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif for (Map::Element *d = profile_data.front(); d; d = d->next()) { d->get().last_frame_call_count = d->get().frame_call_count; @@ -1867,9 +1831,7 @@ void NativeReloadNode::_notification(int p_what) { if (unloaded) break; -#ifndef NO_THREADS MutexLock lock(NSL->mutex); -#endif NSL->_unload_stuff(true); for (Map >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { @@ -1904,9 +1866,8 @@ void NativeReloadNode::_notification(int p_what) { if (!unloaded) break; -#ifndef NO_THREADS MutexLock lock(NSL->mutex); -#endif + Set libs_to_remove; for (Map >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 609ffa2bd4..04670b952b 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -35,6 +35,7 @@ #include "core/io/resource_saver.h" #include "core/oa_hash_map.h" #include "core/ordered_hash_map.h" +#include "core/os/mutex.h" #include "core/os/thread_safe.h" #include "core/resource.h" #include "core/script_language.h" @@ -44,10 +45,6 @@ #include "modules/gdnative/gdnative.h" #include -#ifndef NO_THREADS -#include "core/os/mutex.h" -#endif - struct NativeScriptDesc { struct Method { @@ -127,9 +124,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 instance_owners; protected: @@ -266,9 +261,8 @@ private: void _unload_stuff(bool p_reload = false); + Mutex mutex; #ifndef NO_THREADS - Mutex *mutex; - Set > libs_to_init; Set scripts_to_register; volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 4e39f4b0a8..a40b59bb2e 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -399,39 +399,18 @@ void PluginScriptLanguage::reload_tool_script(const Ref