Modernize RWLock
- Based on C++14's `shared_time_mutex` - No more need to allocate-deallocate or check for null - No pointer anymore, just a member variable - Platform-specific implementations no longer needed - Simpler for `NO_THREADS`
This commit is contained in:
parent
96a3f01ac5
commit
b450036120
23 changed files with 119 additions and 552 deletions
|
@ -929,9 +929,9 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const
|
||||||
|
|
||||||
void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
|
void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
|
||||||
|
|
||||||
lock->read_lock();
|
lock.read_lock();
|
||||||
ClassInfo *type = classes.getptr(p_class);
|
ClassInfo *type = classes.getptr(p_class);
|
||||||
lock->read_unlock();
|
lock.read_unlock();
|
||||||
|
|
||||||
ERR_FAIL_COND(!type);
|
ERR_FAIL_COND(!type);
|
||||||
|
|
||||||
|
@ -1447,12 +1447,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
|
||||||
return default_values[p_class][p_property];
|
return default_values[p_class][p_property];
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLock *ClassDB::lock = NULL;
|
RWLock ClassDB::lock;
|
||||||
|
|
||||||
void ClassDB::init() {
|
|
||||||
|
|
||||||
lock = RWLock::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassDB::cleanup_defaults() {
|
void ClassDB::cleanup_defaults() {
|
||||||
|
|
||||||
|
@ -1479,8 +1474,6 @@ void ClassDB::cleanup() {
|
||||||
classes.clear();
|
classes.clear();
|
||||||
resource_base_extensions.clear();
|
resource_base_extensions.clear();
|
||||||
compat_classes.clear();
|
compat_classes.clear();
|
||||||
|
|
||||||
memdelete(lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -143,7 +143,7 @@ public:
|
||||||
return memnew(T);
|
return memnew(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RWLock *lock;
|
static RWLock lock;
|
||||||
static HashMap<StringName, ClassInfo> classes;
|
static HashMap<StringName, ClassInfo> classes;
|
||||||
static HashMap<StringName, StringName> resource_base_extensions;
|
static HashMap<StringName, StringName> resource_base_extensions;
|
||||||
static HashMap<StringName, StringName> compat_classes;
|
static HashMap<StringName, StringName> compat_classes;
|
||||||
|
@ -393,7 +393,6 @@ public:
|
||||||
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
|
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
|
||||||
|
|
||||||
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
|
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
|
||||||
static void init();
|
|
||||||
|
|
||||||
static void set_current_api(APIType p_api);
|
static void set_current_api(APIType p_api);
|
||||||
static APIType get_current_api();
|
static APIType get_current_api();
|
||||||
|
|
|
@ -362,9 +362,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
|
||||||
}
|
}
|
||||||
|
|
||||||
//lock first if possible
|
//lock first if possible
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.read_lock();
|
||||||
ResourceCache::lock->read_lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
//get ptr
|
//get ptr
|
||||||
Resource **rptr = ResourceCache::resources.getptr(local_path);
|
Resource **rptr = ResourceCache::resources.getptr(local_path);
|
||||||
|
@ -376,16 +374,12 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
|
||||||
//referencing is fine
|
//referencing is fine
|
||||||
if (r_error)
|
if (r_error)
|
||||||
*r_error = OK;
|
*r_error = OK;
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.read_unlock();
|
||||||
ResourceCache::lock->read_unlock();
|
|
||||||
}
|
|
||||||
_remove_from_loading_map(local_path);
|
_remove_from_loading_map(local_path);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.read_unlock();
|
||||||
ResourceCache::lock->read_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xl_remapped = false;
|
bool xl_remapped = false;
|
||||||
|
@ -851,9 +845,7 @@ String ResourceLoader::path_remap(const String &p_path) {
|
||||||
|
|
||||||
void ResourceLoader::reload_translation_remaps() {
|
void ResourceLoader::reload_translation_remaps() {
|
||||||
|
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.read_lock();
|
||||||
ResourceCache::lock->read_lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Resource *> to_reload;
|
List<Resource *> to_reload;
|
||||||
SelfList<Resource> *E = remapped_list.first();
|
SelfList<Resource> *E = remapped_list.first();
|
||||||
|
@ -863,9 +855,7 @@ void ResourceLoader::reload_translation_remaps() {
|
||||||
E = E->next();
|
E = E->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.read_unlock();
|
||||||
ResourceCache::lock->read_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
//now just make sure to not delete any of these resources while changing locale..
|
//now just make sure to not delete any of these resources while changing locale..
|
||||||
while (to_reload.front()) {
|
while (to_reload.front()) {
|
||||||
|
|
|
@ -2068,30 +2068,30 @@ ObjectID ObjectDB::add_instance(Object *p_object) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(p_object->get_instance_id() != 0, 0);
|
ERR_FAIL_COND_V(p_object->get_instance_id() != 0, 0);
|
||||||
|
|
||||||
rw_lock->write_lock();
|
rw_lock.write_lock();
|
||||||
ObjectID instance_id = ++instance_counter;
|
ObjectID instance_id = ++instance_counter;
|
||||||
instances[instance_id] = p_object;
|
instances[instance_id] = p_object;
|
||||||
instance_checks[p_object] = instance_id;
|
instance_checks[p_object] = instance_id;
|
||||||
|
|
||||||
rw_lock->write_unlock();
|
rw_lock.write_unlock();
|
||||||
|
|
||||||
return instance_id;
|
return instance_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectDB::remove_instance(Object *p_object) {
|
void ObjectDB::remove_instance(Object *p_object) {
|
||||||
|
|
||||||
rw_lock->write_lock();
|
rw_lock.write_lock();
|
||||||
|
|
||||||
instances.erase(p_object->get_instance_id());
|
instances.erase(p_object->get_instance_id());
|
||||||
instance_checks.erase(p_object);
|
instance_checks.erase(p_object);
|
||||||
|
|
||||||
rw_lock->write_unlock();
|
rw_lock.write_unlock();
|
||||||
}
|
}
|
||||||
Object *ObjectDB::get_instance(ObjectID p_instance_id) {
|
Object *ObjectDB::get_instance(ObjectID p_instance_id) {
|
||||||
|
|
||||||
rw_lock->read_lock();
|
rw_lock.read_lock();
|
||||||
Object **obj = instances.getptr(p_instance_id);
|
Object **obj = instances.getptr(p_instance_id);
|
||||||
rw_lock->read_unlock();
|
rw_lock.read_unlock();
|
||||||
|
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2100,7 +2100,7 @@ Object *ObjectDB::get_instance(ObjectID p_instance_id) {
|
||||||
|
|
||||||
void ObjectDB::debug_objects(DebugFunc p_func) {
|
void ObjectDB::debug_objects(DebugFunc p_func) {
|
||||||
|
|
||||||
rw_lock->read_lock();
|
rw_lock.read_lock();
|
||||||
|
|
||||||
const ObjectID *K = NULL;
|
const ObjectID *K = NULL;
|
||||||
while ((K = instances.next(K))) {
|
while ((K = instances.next(K))) {
|
||||||
|
@ -2108,7 +2108,7 @@ void ObjectDB::debug_objects(DebugFunc p_func) {
|
||||||
p_func(instances[*K]);
|
p_func(instances[*K]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rw_lock->read_unlock();
|
rw_lock.read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
|
void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
|
||||||
|
@ -2116,23 +2116,18 @@ void Object::get_argument_options(const StringName &p_function, int p_idx, List<
|
||||||
|
|
||||||
int ObjectDB::get_object_count() {
|
int ObjectDB::get_object_count() {
|
||||||
|
|
||||||
rw_lock->read_lock();
|
rw_lock.read_lock();
|
||||||
int count = instances.size();
|
int count = instances.size();
|
||||||
rw_lock->read_unlock();
|
rw_lock.read_unlock();
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLock *ObjectDB::rw_lock = NULL;
|
RWLock ObjectDB::rw_lock;
|
||||||
|
|
||||||
void ObjectDB::setup() {
|
|
||||||
|
|
||||||
rw_lock = RWLock::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectDB::cleanup() {
|
void ObjectDB::cleanup() {
|
||||||
|
|
||||||
rw_lock->write_lock();
|
rw_lock.write_lock();
|
||||||
if (instances.size()) {
|
if (instances.size()) {
|
||||||
|
|
||||||
WARN_PRINT("ObjectDB instances leaked at exit (run with --verbose for details).");
|
WARN_PRINT("ObjectDB instances leaked at exit (run with --verbose for details).");
|
||||||
|
@ -2159,6 +2154,5 @@ void ObjectDB::cleanup() {
|
||||||
}
|
}
|
||||||
instances.clear();
|
instances.clear();
|
||||||
instance_checks.clear();
|
instance_checks.clear();
|
||||||
rw_lock->write_unlock();
|
rw_lock.write_unlock();
|
||||||
memdelete(rw_lock);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,12 +791,11 @@ class ObjectDB {
|
||||||
friend class Object;
|
friend class Object;
|
||||||
friend void unregister_core_types();
|
friend void unregister_core_types();
|
||||||
|
|
||||||
static RWLock *rw_lock;
|
static RWLock rw_lock;
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
static ObjectID add_instance(Object *p_object);
|
static ObjectID add_instance(Object *p_object);
|
||||||
static void remove_instance(Object *p_object);
|
static void remove_instance(Object *p_object);
|
||||||
friend void register_core_types();
|
friend void register_core_types();
|
||||||
static void setup();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef void (*DebugFunc)(Object *p_obj);
|
typedef void (*DebugFunc)(Object *p_obj);
|
||||||
|
@ -806,11 +805,11 @@ public:
|
||||||
static int get_object_count();
|
static int get_object_count();
|
||||||
|
|
||||||
_FORCE_INLINE_ static bool instance_validate(Object *p_ptr) {
|
_FORCE_INLINE_ static bool instance_validate(Object *p_ptr) {
|
||||||
rw_lock->read_lock();
|
rw_lock.read_lock();
|
||||||
|
|
||||||
bool exists = instance_checks.has(p_ptr);
|
bool exists = instance_checks.has(p_ptr);
|
||||||
|
|
||||||
rw_lock->read_unlock();
|
rw_lock.read_unlock();
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rw_lock.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "rw_lock.h"
|
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
RWLock *(*RWLock::create_func)() = 0;
|
|
||||||
|
|
||||||
RWLock *RWLock::create() {
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!create_func, 0);
|
|
||||||
|
|
||||||
return create_func();
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLock::~RWLock() {
|
|
||||||
}
|
|
|
@ -33,49 +33,85 @@
|
||||||
|
|
||||||
#include "core/error_list.h"
|
#include "core/error_list.h"
|
||||||
|
|
||||||
|
#if !defined(NO_THREADS)
|
||||||
|
|
||||||
|
#include <shared_mutex>
|
||||||
|
|
||||||
class RWLock {
|
class RWLock {
|
||||||
protected:
|
mutable std::shared_timed_mutex mutex;
|
||||||
static RWLock *(*create_func)();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void read_lock() = 0; ///< Lock the rwlock, block if locked by someone else
|
// Lock the rwlock, block if locked by someone else
|
||||||
virtual void read_unlock() = 0; ///< Unlock the rwlock, let other threads continue
|
void read_lock() const {
|
||||||
virtual Error read_try_lock() = 0; ///< Attempt to lock the rwlock, OK on success, ERROR means it can't lock.
|
mutex.lock_shared();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void write_lock() = 0; ///< Lock the rwlock, block if locked by someone else
|
// Unlock the rwlock, let other threads continue
|
||||||
virtual void write_unlock() = 0; ///< Unlock the rwlock, let other thwrites continue
|
void read_unlock() const {
|
||||||
virtual Error write_try_lock() = 0; ///< Attempt to lock the rwlock, OK on success, ERROR means it can't lock.
|
mutex.unlock_shared();
|
||||||
|
}
|
||||||
|
|
||||||
static RWLock *create(); ///< Create a rwlock
|
// Attempt to lock the rwlock, OK on success, ERR_BUSY means it can't lock.
|
||||||
|
Error read_try_lock() const {
|
||||||
|
return mutex.try_lock_shared() ? OK : ERR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~RWLock();
|
// Lock the rwlock, block if locked by someone else
|
||||||
|
void write_lock() {
|
||||||
|
mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock the rwlock, let other thwrites continue
|
||||||
|
void write_unlock() {
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to lock the rwlock, OK on success, ERR_BUSY means it can't lock.
|
||||||
|
Error write_try_lock() {
|
||||||
|
return mutex.try_lock() ? OK : ERR_BUSY;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
class RWLock {
|
||||||
|
public:
|
||||||
|
void read_lock() const {}
|
||||||
|
void read_unlock() const {}
|
||||||
|
Error read_try_lock() const { return OK; }
|
||||||
|
|
||||||
|
void write_lock() {}
|
||||||
|
void write_unlock() {}
|
||||||
|
Error write_try_lock() { return OK; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class RWLockRead {
|
class RWLockRead {
|
||||||
|
|
||||||
RWLock *lock;
|
const RWLock &lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RWLockRead(const RWLock *p_lock) {
|
RWLockRead(const RWLock &p_lock) :
|
||||||
lock = const_cast<RWLock *>(p_lock);
|
lock(p_lock) {
|
||||||
if (lock) lock->read_lock();
|
lock.read_lock();
|
||||||
}
|
}
|
||||||
~RWLockRead() {
|
~RWLockRead() {
|
||||||
if (lock) lock->read_unlock();
|
lock.read_unlock();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RWLockWrite {
|
class RWLockWrite {
|
||||||
|
|
||||||
RWLock *lock;
|
RWLock &lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RWLockWrite(RWLock *p_lock) {
|
RWLockWrite(RWLock &p_lock) :
|
||||||
lock = p_lock;
|
lock(p_lock) {
|
||||||
if (lock) lock->write_lock();
|
lock.write_lock();
|
||||||
}
|
}
|
||||||
~RWLockWrite() {
|
~RWLockWrite() {
|
||||||
if (lock) lock->write_unlock();
|
lock.write_unlock();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -55,11 +55,3 @@ Semaphore *SemaphoreDummy::create() {
|
||||||
void SemaphoreDummy::make_default() {
|
void SemaphoreDummy::make_default() {
|
||||||
Semaphore::create_func = &SemaphoreDummy::create;
|
Semaphore::create_func = &SemaphoreDummy::create;
|
||||||
};
|
};
|
||||||
|
|
||||||
RWLock *RWLockDummy::create() {
|
|
||||||
return memnew(RWLockDummy);
|
|
||||||
};
|
|
||||||
|
|
||||||
void RWLockDummy::make_default() {
|
|
||||||
RWLock::create_func = &RWLockDummy::create;
|
|
||||||
};
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#define THREAD_DUMMY_H
|
#define THREAD_DUMMY_H
|
||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/rw_lock.h"
|
|
||||||
#include "core/os/semaphore.h"
|
#include "core/os/semaphore.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
|
||||||
|
@ -70,20 +69,4 @@ public:
|
||||||
static void make_default();
|
static void make_default();
|
||||||
};
|
};
|
||||||
|
|
||||||
class RWLockDummy : public RWLock {
|
|
||||||
|
|
||||||
static RWLock *create();
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void read_lock() {}
|
|
||||||
virtual void read_unlock() {}
|
|
||||||
virtual Error read_try_lock() { return OK; }
|
|
||||||
|
|
||||||
virtual void write_lock() {}
|
|
||||||
virtual void write_unlock() {}
|
|
||||||
virtual Error write_try_lock() { return OK; }
|
|
||||||
|
|
||||||
static void make_default();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,8 +99,6 @@ extern void unregister_variant_methods();
|
||||||
|
|
||||||
void register_core_types() {
|
void register_core_types() {
|
||||||
|
|
||||||
ObjectDB::setup();
|
|
||||||
ResourceCache::setup();
|
|
||||||
MemoryPool::setup();
|
MemoryPool::setup();
|
||||||
|
|
||||||
_global_mutex = Mutex::create();
|
_global_mutex = Mutex::create();
|
||||||
|
|
|
@ -54,30 +54,30 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
|
||||||
|
|
||||||
if (path_cache != "") {
|
if (path_cache != "") {
|
||||||
|
|
||||||
ResourceCache::lock->write_lock();
|
ResourceCache::lock.write_lock();
|
||||||
ResourceCache::resources.erase(path_cache);
|
ResourceCache::resources.erase(path_cache);
|
||||||
ResourceCache::lock->write_unlock();
|
ResourceCache::lock.write_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
path_cache = "";
|
path_cache = "";
|
||||||
|
|
||||||
ResourceCache::lock->read_lock();
|
ResourceCache::lock.read_lock();
|
||||||
bool has_path = ResourceCache::resources.has(p_path);
|
bool has_path = ResourceCache::resources.has(p_path);
|
||||||
ResourceCache::lock->read_unlock();
|
ResourceCache::lock.read_unlock();
|
||||||
|
|
||||||
if (has_path) {
|
if (has_path) {
|
||||||
if (p_take_over) {
|
if (p_take_over) {
|
||||||
|
|
||||||
ResourceCache::lock->write_lock();
|
ResourceCache::lock.write_lock();
|
||||||
Resource **res = ResourceCache::resources.getptr(p_path);
|
Resource **res = ResourceCache::resources.getptr(p_path);
|
||||||
if (res) {
|
if (res) {
|
||||||
(*res)->set_name("");
|
(*res)->set_name("");
|
||||||
}
|
}
|
||||||
ResourceCache::lock->write_unlock();
|
ResourceCache::lock.write_unlock();
|
||||||
} else {
|
} else {
|
||||||
ResourceCache::lock->read_lock();
|
ResourceCache::lock.read_lock();
|
||||||
bool exists = ResourceCache::resources.has(p_path);
|
bool exists = ResourceCache::resources.has(p_path);
|
||||||
ResourceCache::lock->read_unlock();
|
ResourceCache::lock.read_unlock();
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion).");
|
ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion).");
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,9 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
|
||||||
|
|
||||||
if (path_cache != "") {
|
if (path_cache != "") {
|
||||||
|
|
||||||
ResourceCache::lock->write_lock();
|
ResourceCache::lock.write_lock();
|
||||||
ResourceCache::resources[path_cache] = this;
|
ResourceCache::resources[path_cache] = this;
|
||||||
ResourceCache::lock->write_unlock();
|
ResourceCache::lock.write_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
_change_notify("resource_path");
|
_change_notify("resource_path");
|
||||||
|
@ -343,9 +343,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
|
||||||
if (remapped_list.in_list() == p_remapped)
|
if (remapped_list.in_list() == p_remapped)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.write_lock();
|
||||||
ResourceCache::lock->write_lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_remapped) {
|
if (p_remapped) {
|
||||||
ResourceLoader::remapped_list.add(&remapped_list);
|
ResourceLoader::remapped_list.add(&remapped_list);
|
||||||
|
@ -353,9 +351,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
|
||||||
ResourceLoader::remapped_list.remove(&remapped_list);
|
ResourceLoader::remapped_list.remove(&remapped_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ResourceCache::lock) {
|
ResourceCache::lock.write_unlock();
|
||||||
ResourceCache::lock->write_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resource::is_translation_remapped() const {
|
bool Resource::is_translation_remapped() const {
|
||||||
|
@ -367,38 +363,24 @@ bool Resource::is_translation_remapped() const {
|
||||||
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
|
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
|
||||||
void Resource::set_id_for_path(const String &p_path, int p_id) {
|
void Resource::set_id_for_path(const String &p_path, int p_id) {
|
||||||
if (p_id == -1) {
|
if (p_id == -1) {
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.write_lock();
|
||||||
ResourceCache::path_cache_lock->write_lock();
|
|
||||||
}
|
|
||||||
ResourceCache::resource_path_cache[p_path].erase(get_path());
|
ResourceCache::resource_path_cache[p_path].erase(get_path());
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.write_unlock();
|
||||||
ResourceCache::path_cache_lock->write_unlock();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.write_lock();
|
||||||
ResourceCache::path_cache_lock->write_lock();
|
|
||||||
}
|
|
||||||
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
|
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.write_unlock();
|
||||||
ResourceCache::path_cache_lock->write_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Resource::get_id_for_path(const String &p_path) const {
|
int Resource::get_id_for_path(const String &p_path) const {
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.read_lock();
|
||||||
ResourceCache::path_cache_lock->read_lock();
|
|
||||||
}
|
|
||||||
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
|
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
|
||||||
int result = ResourceCache::resource_path_cache[p_path][get_path()];
|
int result = ResourceCache::resource_path_cache[p_path][get_path()];
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.read_unlock();
|
||||||
ResourceCache::path_cache_lock->read_unlock();
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
if (ResourceCache::path_cache_lock) {
|
ResourceCache::path_cache_lock.read_unlock();
|
||||||
ResourceCache::path_cache_lock->read_unlock();
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,9 +426,9 @@ Resource::Resource() :
|
||||||
Resource::~Resource() {
|
Resource::~Resource() {
|
||||||
|
|
||||||
if (path_cache != "") {
|
if (path_cache != "") {
|
||||||
ResourceCache::lock->write_lock();
|
ResourceCache::lock.write_lock();
|
||||||
ResourceCache::resources.erase(path_cache);
|
ResourceCache::resources.erase(path_cache);
|
||||||
ResourceCache::lock->write_unlock();
|
ResourceCache::lock.write_unlock();
|
||||||
}
|
}
|
||||||
if (owners.size()) {
|
if (owners.size()) {
|
||||||
WARN_PRINT("Resource is still owned.");
|
WARN_PRINT("Resource is still owned.");
|
||||||
|
@ -458,19 +440,11 @@ HashMap<String, Resource *> ResourceCache::resources;
|
||||||
HashMap<String, HashMap<String, int> > ResourceCache::resource_path_cache;
|
HashMap<String, HashMap<String, int> > ResourceCache::resource_path_cache;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RWLock *ResourceCache::lock = NULL;
|
RWLock ResourceCache::lock;
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
RWLock *ResourceCache::path_cache_lock = NULL;
|
RWLock ResourceCache::path_cache_lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ResourceCache::setup() {
|
|
||||||
|
|
||||||
lock = RWLock::create();
|
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
path_cache_lock = RWLock::create();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceCache::clear() {
|
void ResourceCache::clear() {
|
||||||
if (resources.size()) {
|
if (resources.size()) {
|
||||||
ERR_PRINT("Resources still in use at exit (run with --verbose for details).");
|
ERR_PRINT("Resources still in use at exit (run with --verbose for details).");
|
||||||
|
@ -484,7 +458,6 @@ void ResourceCache::clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
resources.clear();
|
resources.clear();
|
||||||
memdelete(lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::reload_externals() {
|
void ResourceCache::reload_externals() {
|
||||||
|
@ -492,19 +465,19 @@ void ResourceCache::reload_externals() {
|
||||||
|
|
||||||
bool ResourceCache::has(const String &p_path) {
|
bool ResourceCache::has(const String &p_path) {
|
||||||
|
|
||||||
lock->read_lock();
|
lock.read_lock();
|
||||||
bool b = resources.has(p_path);
|
bool b = resources.has(p_path);
|
||||||
lock->read_unlock();
|
lock.read_unlock();
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
Resource *ResourceCache::get(const String &p_path) {
|
Resource *ResourceCache::get(const String &p_path) {
|
||||||
|
|
||||||
lock->read_lock();
|
lock.read_lock();
|
||||||
|
|
||||||
Resource **res = resources.getptr(p_path);
|
Resource **res = resources.getptr(p_path);
|
||||||
|
|
||||||
lock->read_unlock();
|
lock.read_unlock();
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -515,28 +488,28 @@ Resource *ResourceCache::get(const String &p_path) {
|
||||||
|
|
||||||
void ResourceCache::get_cached_resources(List<Ref<Resource> > *p_resources) {
|
void ResourceCache::get_cached_resources(List<Ref<Resource> > *p_resources) {
|
||||||
|
|
||||||
lock->read_lock();
|
lock.read_lock();
|
||||||
const String *K = NULL;
|
const String *K = NULL;
|
||||||
while ((K = resources.next(K))) {
|
while ((K = resources.next(K))) {
|
||||||
|
|
||||||
Resource *r = resources[*K];
|
Resource *r = resources[*K];
|
||||||
p_resources->push_back(Ref<Resource>(r));
|
p_resources->push_back(Ref<Resource>(r));
|
||||||
}
|
}
|
||||||
lock->read_unlock();
|
lock.read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ResourceCache::get_cached_resource_count() {
|
int ResourceCache::get_cached_resource_count() {
|
||||||
|
|
||||||
lock->read_lock();
|
lock.read_lock();
|
||||||
int rc = resources.size();
|
int rc = resources.size();
|
||||||
lock->read_unlock();
|
lock.read_unlock();
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::dump(const char *p_file, bool p_short) {
|
void ResourceCache::dump(const char *p_file, bool p_short) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
lock->read_lock();
|
lock.read_lock();
|
||||||
|
|
||||||
Map<String, int> type_count;
|
Map<String, int> type_count;
|
||||||
|
|
||||||
|
@ -573,6 +546,6 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
|
||||||
memdelete(f);
|
memdelete(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock->read_unlock();
|
lock.read_unlock();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,16 +148,15 @@ typedef Ref<Resource> RES;
|
||||||
class ResourceCache {
|
class ResourceCache {
|
||||||
friend class Resource;
|
friend class Resource;
|
||||||
friend class ResourceLoader; //need the lock
|
friend class ResourceLoader; //need the lock
|
||||||
static RWLock *lock;
|
static RWLock lock;
|
||||||
static HashMap<String, Resource *> resources;
|
static HashMap<String, Resource *> resources;
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
static HashMap<String, HashMap<String, int> > resource_path_cache; // each tscn has a set of resource paths and IDs
|
static HashMap<String, HashMap<String, int> > resource_path_cache; // each tscn has a set of resource paths and IDs
|
||||||
static RWLock *path_cache_lock;
|
static RWLock path_cache_lock;
|
||||||
#endif // TOOLS_ENABLED
|
#endif // TOOLS_ENABLED
|
||||||
friend void unregister_core_types();
|
friend void unregister_core_types();
|
||||||
static void clear();
|
static void clear();
|
||||||
friend void register_core_types();
|
friend void register_core_types();
|
||||||
static void setup();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void reload_externals();
|
static void reload_externals();
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "drivers/unix/file_access_unix.h"
|
#include "drivers/unix/file_access_unix.h"
|
||||||
#include "drivers/unix/mutex_posix.h"
|
#include "drivers/unix/mutex_posix.h"
|
||||||
#include "drivers/unix/net_socket_posix.h"
|
#include "drivers/unix/net_socket_posix.h"
|
||||||
#include "drivers/unix/rw_lock_posix.h"
|
|
||||||
#include "drivers/unix/semaphore_posix.h"
|
#include "drivers/unix/semaphore_posix.h"
|
||||||
#include "drivers/unix/thread_posix.h"
|
#include "drivers/unix/thread_posix.h"
|
||||||
#include "servers/visual_server.h"
|
#include "servers/visual_server.h"
|
||||||
|
@ -124,14 +123,12 @@ void OS_Unix::initialize_core() {
|
||||||
ThreadDummy::make_default();
|
ThreadDummy::make_default();
|
||||||
SemaphoreDummy::make_default();
|
SemaphoreDummy::make_default();
|
||||||
MutexDummy::make_default();
|
MutexDummy::make_default();
|
||||||
RWLockDummy::make_default();
|
|
||||||
#else
|
#else
|
||||||
ThreadPosix::make_default();
|
ThreadPosix::make_default();
|
||||||
#if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED)
|
#if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED)
|
||||||
SemaphorePosix::make_default();
|
SemaphorePosix::make_default();
|
||||||
#endif
|
#endif
|
||||||
MutexPosix::make_default();
|
MutexPosix::make_default();
|
||||||
RWLockPosix::make_default();
|
|
||||||
#endif
|
#endif
|
||||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
||||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
|
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rw_lock_posix.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
|
|
||||||
|
|
||||||
#include "rw_lock_posix.h"
|
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
|
||||||
#include "core/os/memory.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void RWLockPosix::read_lock() {
|
|
||||||
|
|
||||||
int err = pthread_rwlock_rdlock(&rwlock);
|
|
||||||
if (err != 0) {
|
|
||||||
perror("Acquiring lock failed");
|
|
||||||
}
|
|
||||||
ERR_FAIL_COND(err != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockPosix::read_unlock() {
|
|
||||||
|
|
||||||
pthread_rwlock_unlock(&rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error RWLockPosix::read_try_lock() {
|
|
||||||
|
|
||||||
if (pthread_rwlock_tryrdlock(&rwlock) != 0) {
|
|
||||||
return ERR_BUSY;
|
|
||||||
} else {
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockPosix::write_lock() {
|
|
||||||
|
|
||||||
int err = pthread_rwlock_wrlock(&rwlock);
|
|
||||||
ERR_FAIL_COND(err != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockPosix::write_unlock() {
|
|
||||||
|
|
||||||
pthread_rwlock_unlock(&rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error RWLockPosix::write_try_lock() {
|
|
||||||
if (pthread_rwlock_trywrlock(&rwlock) != 0) {
|
|
||||||
return ERR_BUSY;
|
|
||||||
} else {
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLock *RWLockPosix::create_func_posix() {
|
|
||||||
|
|
||||||
return memnew(RWLockPosix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockPosix::make_default() {
|
|
||||||
|
|
||||||
create_func = create_func_posix;
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLockPosix::RWLockPosix() {
|
|
||||||
|
|
||||||
//rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX
|
|
||||||
pthread_rwlock_init(&rwlock, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLockPosix::~RWLockPosix() {
|
|
||||||
|
|
||||||
pthread_rwlock_destroy(&rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rw_lock_posix.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RWLOCKPOSIX_H
|
|
||||||
#define RWLOCKPOSIX_H
|
|
||||||
|
|
||||||
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
|
|
||||||
|
|
||||||
#include "core/os/rw_lock.h"
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
class RWLockPosix : public RWLock {
|
|
||||||
|
|
||||||
pthread_rwlock_t rwlock;
|
|
||||||
|
|
||||||
static RWLock *create_func_posix();
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void read_lock();
|
|
||||||
virtual void read_unlock();
|
|
||||||
virtual Error read_try_lock();
|
|
||||||
|
|
||||||
virtual void write_lock();
|
|
||||||
virtual void write_unlock();
|
|
||||||
virtual Error write_try_lock();
|
|
||||||
|
|
||||||
static void make_default();
|
|
||||||
|
|
||||||
RWLockPosix();
|
|
||||||
|
|
||||||
~RWLockPosix();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RWLOCKPOSIX_H
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rw_lock_windows.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#if defined(WINDOWS_ENABLED)
|
|
||||||
|
|
||||||
#include "rw_lock_windows.h"
|
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
|
||||||
#include "core/os/memory.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void RWLockWindows::read_lock() {
|
|
||||||
|
|
||||||
AcquireSRWLockShared(&lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockWindows::read_unlock() {
|
|
||||||
|
|
||||||
ReleaseSRWLockShared(&lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error RWLockWindows::read_try_lock() {
|
|
||||||
|
|
||||||
if (TryAcquireSRWLockShared(&lock) == 0) {
|
|
||||||
return ERR_BUSY;
|
|
||||||
} else {
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockWindows::write_lock() {
|
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockWindows::write_unlock() {
|
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error RWLockWindows::write_try_lock() {
|
|
||||||
if (TryAcquireSRWLockExclusive(&lock) == 0) {
|
|
||||||
return ERR_BUSY;
|
|
||||||
} else {
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLock *RWLockWindows::create_func_windows() {
|
|
||||||
|
|
||||||
return memnew(RWLockWindows);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RWLockWindows::make_default() {
|
|
||||||
|
|
||||||
create_func = create_func_windows;
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLockWindows::RWLockWindows() {
|
|
||||||
|
|
||||||
InitializeSRWLock(&lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLockWindows::~RWLockWindows() {
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,64 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rw_lock_windows.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RWLOCKWINDOWS_H
|
|
||||||
#define RWLOCKWINDOWS_H
|
|
||||||
|
|
||||||
#if defined(WINDOWS_ENABLED)
|
|
||||||
|
|
||||||
#include "core/os/rw_lock.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
class RWLockWindows : public RWLock {
|
|
||||||
|
|
||||||
SRWLOCK lock;
|
|
||||||
|
|
||||||
static RWLock *create_func_windows();
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void read_lock();
|
|
||||||
virtual void read_unlock();
|
|
||||||
virtual Error read_try_lock();
|
|
||||||
|
|
||||||
virtual void write_lock();
|
|
||||||
virtual void write_unlock();
|
|
||||||
virtual Error write_try_lock();
|
|
||||||
|
|
||||||
static void make_default();
|
|
||||||
|
|
||||||
RWLockWindows();
|
|
||||||
|
|
||||||
~RWLockWindows();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RWLOCKWINDOWS_H
|
|
|
@ -352,8 +352,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||||
|
|
||||||
engine = memnew(Engine);
|
engine = memnew(Engine);
|
||||||
|
|
||||||
ClassDB::init();
|
|
||||||
|
|
||||||
MAIN_PRINT("Main: Initialize CORE");
|
MAIN_PRINT("Main: Initialize CORE");
|
||||||
|
|
||||||
register_core_types();
|
register_core_types();
|
||||||
|
|
|
@ -85,8 +85,8 @@ def configure(env):
|
||||||
env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"])
|
env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"])
|
||||||
else:
|
else:
|
||||||
print("Building for macOS 10.9+, platform x86-64.")
|
print("Building for macOS 10.9+, platform x86-64.")
|
||||||
env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.9"])
|
env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
|
||||||
env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.9"])
|
env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
|
||||||
|
|
||||||
if not "osxcross" in env: # regular native build
|
if not "osxcross" in env: # regular native build
|
||||||
if env["macports_clang"] != "no":
|
if env["macports_clang"] != "no":
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "drivers/windows/dir_access_windows.h"
|
#include "drivers/windows/dir_access_windows.h"
|
||||||
#include "drivers/windows/file_access_windows.h"
|
#include "drivers/windows/file_access_windows.h"
|
||||||
#include "drivers/windows/mutex_windows.h"
|
#include "drivers/windows/mutex_windows.h"
|
||||||
#include "drivers/windows/rw_lock_windows.h"
|
|
||||||
#include "drivers/windows/semaphore_windows.h"
|
#include "drivers/windows/semaphore_windows.h"
|
||||||
#include "main/main.h"
|
#include "main/main.h"
|
||||||
#include "platform/windows/windows_terminal_logger.h"
|
#include "platform/windows/windows_terminal_logger.h"
|
||||||
|
@ -143,7 +142,6 @@ void OS_UWP::initialize_core() {
|
||||||
ThreadUWP::make_default();
|
ThreadUWP::make_default();
|
||||||
SemaphoreWindows::make_default();
|
SemaphoreWindows::make_default();
|
||||||
MutexWindows::make_default();
|
MutexWindows::make_default();
|
||||||
RWLockWindows::make_default();
|
|
||||||
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
|
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "drivers/windows/dir_access_windows.h"
|
#include "drivers/windows/dir_access_windows.h"
|
||||||
#include "drivers/windows/file_access_windows.h"
|
#include "drivers/windows/file_access_windows.h"
|
||||||
#include "drivers/windows/mutex_windows.h"
|
#include "drivers/windows/mutex_windows.h"
|
||||||
#include "drivers/windows/rw_lock_windows.h"
|
|
||||||
#include "drivers/windows/semaphore_windows.h"
|
#include "drivers/windows/semaphore_windows.h"
|
||||||
#include "drivers/windows/thread_windows.h"
|
#include "drivers/windows/thread_windows.h"
|
||||||
#include "joypad_windows.h"
|
#include "joypad_windows.h"
|
||||||
|
@ -230,7 +229,6 @@ void OS_Windows::initialize_core() {
|
||||||
ThreadWindows::make_default();
|
ThreadWindows::make_default();
|
||||||
SemaphoreWindows::make_default();
|
SemaphoreWindows::make_default();
|
||||||
MutexWindows::make_default();
|
MutexWindows::make_default();
|
||||||
RWLockWindows::make_default();
|
|
||||||
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
|
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
|
||||||
|
|
|
@ -2218,19 +2218,10 @@ AnimatedTexture::AnimatedTexture() {
|
||||||
pause = false;
|
pause = false;
|
||||||
oneshot = false;
|
oneshot = false;
|
||||||
VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
|
VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
rw_lock = RWLock::create();
|
|
||||||
#else
|
|
||||||
rw_lock = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedTexture::~AnimatedTexture() {
|
AnimatedTexture::~AnimatedTexture() {
|
||||||
VS::get_singleton()->free(proxy);
|
VS::get_singleton()->free(proxy);
|
||||||
if (rw_lock) {
|
|
||||||
memdelete(rw_lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -679,7 +679,7 @@ class AnimatedTexture : public Texture {
|
||||||
GDCLASS(AnimatedTexture, Texture);
|
GDCLASS(AnimatedTexture, Texture);
|
||||||
|
|
||||||
//use readers writers lock for this, since its far more times read than written to
|
//use readers writers lock for this, since its far more times read than written to
|
||||||
RWLock *rw_lock;
|
RWLock rw_lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
|
|
Loading…
Add table
Reference in a new issue