diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-02-28 00:26:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-28 00:26:01 +0100 |
commit | b7b39786840a41a057f531ed13b64e26366befac (patch) | |
tree | b78a2e0bc0b3f49e82e148e8edb741930ff0ce55 /core | |
parent | e66d519286693a03bf59eaba0a5f29c1c9b15d64 (diff) | |
parent | 18fbdbb456c07a56b358bea2e392765fbcbb3283 (diff) |
Merge pull request #36556 from RandomShaper/rework_mutex
Reimplement `Mutex` with C++'s `<mutex>` (plus more)
Diffstat (limited to 'core')
-rw-r--r-- | core/bind/core_bind.cpp | 16 | ||||
-rw-r--r-- | core/bind/core_bind.h | 5 | ||||
-rw-r--r-- | core/command_queue_mt.cpp | 8 | ||||
-rw-r--r-- | core/command_queue_mt.h | 2 | ||||
-rw-r--r-- | core/io/file_access_network.cpp | 61 | ||||
-rw-r--r-- | core/io/file_access_network.h | 6 | ||||
-rw-r--r-- | core/io/ip.cpp | 42 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 31 | ||||
-rw-r--r-- | core/io/resource_loader.h | 2 | ||||
-rw-r--r-- | core/os/mutex.cpp | 32 | ||||
-rw-r--r-- | core/os/mutex.h | 73 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | core/os/thread_dummy.cpp | 8 | ||||
-rw-r--r-- | core/os/thread_dummy.h | 13 | ||||
-rw-r--r-- | core/os/thread_safe.cpp | 49 | ||||
-rw-r--r-- | core/os/thread_safe.h | 49 | ||||
-rw-r--r-- | core/register_core_types.cpp | 9 | ||||
-rw-r--r-- | core/script_debugger_remote.cpp | 32 | ||||
-rw-r--r-- | core/script_debugger_remote.h | 2 | ||||
-rw-r--r-- | core/string_name.cpp | 42 | ||||
-rw-r--r-- | core/string_name.h | 2 |
21 files changed, 147 insertions, 339 deletions
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 <class T> 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<uint8_t> &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; - - 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(); + { + MutexLock lock(nc->blockrequest_mutex); + + 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<int, FileAccessNetwork *> accesses; Ref<StreamPeerTCP> 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::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> 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<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 { 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 <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); -} - -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(); +void _global_unlock() { + _global_mutex.unlock(); } + +template class MutexImpl<std::recursive_mutex>; +template class MutexImpl<std::mutex>; +template class MutexLock<MutexImpl<std::recursive_mutex> >; +template class MutexLock<MutexImpl<std::mutex> >; 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 <mutex> + +template <class StdMutexT> +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 MutexT> 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 StdMutexType> +class MutexImpl { +public: + _ALWAYS_INLINE_ void lock() const {} + _ALWAYS_INLINE_ void unlock() const {} + _ALWAYS_INLINE_ Error try_lock() const { return OK; } +}; + +template <class MutexT> +class MutexLock { +public: + explicit MutexLock(const MutexT &p_mutex) {} +}; + +#endif // !NO_THREADS + +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>; +extern template class MutexLock<MutexImpl<std::recursive_mutex> >; +extern template class MutexLock<MutexImpl<std::mutex> >; + #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 <stdarg.h> -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<ScriptLanguage::StackInfo> &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<String> output_strings; List<Message> 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; |