Reimplement Mutex with C++'s <mutex>
Main: - It's now implemented thanks to `<mutex>`. 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`.
This commit is contained in:
parent
1e57b558f2
commit
18fbdbb456
|
@ -2583,17 +2583,17 @@ _Semaphore::~_Semaphore() {
|
||||||
|
|
||||||
void _Mutex::lock() {
|
void _Mutex::lock() {
|
||||||
|
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error _Mutex::try_lock() {
|
Error _Mutex::try_lock() {
|
||||||
|
|
||||||
return mutex->try_lock();
|
return mutex.try_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _Mutex::unlock() {
|
void _Mutex::unlock() {
|
||||||
|
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _Mutex::_bind_methods() {
|
void _Mutex::_bind_methods() {
|
||||||
|
@ -2603,16 +2603,6 @@ void _Mutex::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock);
|
ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Mutex::_Mutex() {
|
|
||||||
|
|
||||||
mutex = Mutex::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
_Mutex::~_Mutex() {
|
|
||||||
|
|
||||||
memdelete(mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
|
||||||
void _Thread::_start_func(void *ud) {
|
void _Thread::_start_func(void *ud) {
|
||||||
|
|
|
@ -609,7 +609,7 @@ public:
|
||||||
class _Mutex : public Reference {
|
class _Mutex : public Reference {
|
||||||
|
|
||||||
GDCLASS(_Mutex, Reference);
|
GDCLASS(_Mutex, Reference);
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
@ -617,9 +617,6 @@ public:
|
||||||
void lock();
|
void lock();
|
||||||
Error try_lock();
|
Error try_lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|
||||||
_Mutex();
|
|
||||||
~_Mutex();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class _Semaphore : public Reference {
|
class _Semaphore : public Reference {
|
||||||
|
|
|
@ -34,14 +34,12 @@
|
||||||
|
|
||||||
void CommandQueueMT::lock() {
|
void CommandQueueMT::lock() {
|
||||||
|
|
||||||
if (mutex)
|
mutex.lock();
|
||||||
mutex->lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandQueueMT::unlock() {
|
void CommandQueueMT::unlock() {
|
||||||
|
|
||||||
if (mutex)
|
mutex.unlock();
|
||||||
mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandQueueMT::wait_for_flush() {
|
void CommandQueueMT::wait_for_flush() {
|
||||||
|
@ -106,7 +104,6 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
|
||||||
read_ptr = 0;
|
read_ptr = 0;
|
||||||
write_ptr = 0;
|
write_ptr = 0;
|
||||||
dealloc_ptr = 0;
|
dealloc_ptr = 0;
|
||||||
mutex = Mutex::create();
|
|
||||||
command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
|
command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
|
||||||
|
|
||||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||||
|
@ -124,7 +121,6 @@ CommandQueueMT::~CommandQueueMT() {
|
||||||
|
|
||||||
if (sync)
|
if (sync)
|
||||||
memdelete(sync);
|
memdelete(sync);
|
||||||
memdelete(mutex);
|
|
||||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||||
|
|
||||||
memdelete(sync_sems[i].sem);
|
memdelete(sync_sems[i].sem);
|
||||||
|
|
|
@ -341,7 +341,7 @@ class CommandQueueMT {
|
||||||
uint32_t write_ptr;
|
uint32_t write_ptr;
|
||||||
uint32_t dealloc_ptr;
|
uint32_t dealloc_ptr;
|
||||||
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
SemaphoreOld *sync;
|
SemaphoreOld *sync;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -42,14 +42,14 @@
|
||||||
|
|
||||||
void FileAccessNetworkClient::lock_mutex() {
|
void FileAccessNetworkClient::lock_mutex() {
|
||||||
|
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
lockcount++;
|
lockcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccessNetworkClient::unlock_mutex() {
|
void FileAccessNetworkClient::unlock_mutex() {
|
||||||
|
|
||||||
lockcount--;
|
lockcount--;
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccessNetworkClient::put_32(int p_32) {
|
void FileAccessNetworkClient::put_32(int p_32) {
|
||||||
|
@ -97,7 +97,8 @@ void FileAccessNetworkClient::_thread_func() {
|
||||||
lock_mutex();
|
lock_mutex();
|
||||||
DEBUG_PRINT("MUTEX PASS");
|
DEBUG_PRINT("MUTEX PASS");
|
||||||
|
|
||||||
blockrequest_mutex->lock();
|
{
|
||||||
|
MutexLock lock(blockrequest_mutex);
|
||||||
while (block_requests.size()) {
|
while (block_requests.size()) {
|
||||||
put_32(block_requests.front()->get().id);
|
put_32(block_requests.front()->get().id);
|
||||||
put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
|
put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
|
||||||
|
@ -105,7 +106,7 @@ void FileAccessNetworkClient::_thread_func() {
|
||||||
put_32(block_requests.front()->get().size);
|
put_32(block_requests.front()->get().size);
|
||||||
block_requests.pop_front();
|
block_requests.pop_front();
|
||||||
}
|
}
|
||||||
blockrequest_mutex->unlock();
|
}
|
||||||
|
|
||||||
DEBUG_PRINT("THREAD ITER");
|
DEBUG_PRINT("THREAD ITER");
|
||||||
|
|
||||||
|
@ -225,8 +226,6 @@ FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL;
|
||||||
FileAccessNetworkClient::FileAccessNetworkClient() {
|
FileAccessNetworkClient::FileAccessNetworkClient() {
|
||||||
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
mutex = Mutex::create();
|
|
||||||
blockrequest_mutex = Mutex::create();
|
|
||||||
quit = false;
|
quit = false;
|
||||||
singleton = this;
|
singleton = this;
|
||||||
last_id = 0;
|
last_id = 0;
|
||||||
|
@ -244,8 +243,6 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
|
||||||
memdelete(thread);
|
memdelete(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete(blockrequest_mutex);
|
|
||||||
memdelete(mutex);
|
|
||||||
memdelete(sem);
|
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)));
|
ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_mutex->lock();
|
{
|
||||||
|
MutexLock lock(buffer_mutex);
|
||||||
pages.write[page].buffer = p_block;
|
pages.write[page].buffer = p_block;
|
||||||
pages.write[page].queued = false;
|
pages.write[page].queued = false;
|
||||||
buffer_mutex->unlock();
|
}
|
||||||
|
|
||||||
if (waiting_on_page == page) {
|
if (waiting_on_page == page) {
|
||||||
waiting_on_page = -1;
|
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) {
|
if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
|
||||||
|
|
||||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||||
|
{
|
||||||
|
MutexLock lock(nc->blockrequest_mutex);
|
||||||
|
|
||||||
nc->blockrequest_mutex->lock();
|
|
||||||
FileAccessNetworkClient::BlockRequest br;
|
FileAccessNetworkClient::BlockRequest br;
|
||||||
br.id = id;
|
br.id = id;
|
||||||
br.offset = size_t(p_page) * page_size;
|
br.offset = size_t(p_page) * page_size;
|
||||||
br.size = page_size;
|
br.size = page_size;
|
||||||
nc->block_requests.push_back(br);
|
nc->block_requests.push_back(br);
|
||||||
pages.write[p_page].queued = true;
|
pages.write[p_page].queued = true;
|
||||||
nc->blockrequest_mutex->unlock();
|
}
|
||||||
DEBUG_PRINT("QUEUE PAGE POST");
|
DEBUG_PRINT("QUEUE PAGE POST");
|
||||||
nc->sem->post();
|
nc->sem->post();
|
||||||
DEBUG_PRINT("queued " + itos(p_page));
|
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;
|
int page = pos / page_size;
|
||||||
|
|
||||||
if (page != last_page) {
|
if (page != last_page) {
|
||||||
buffer_mutex->lock();
|
buffer_mutex.lock();
|
||||||
if (pages[page].buffer.empty()) {
|
if (pages[page].buffer.empty()) {
|
||||||
waiting_on_page = page;
|
waiting_on_page = page;
|
||||||
for (int j = 0; j < read_ahead; j++) {
|
for (int j = 0; j < read_ahead; j++) {
|
||||||
|
|
||||||
_queue_page(page + j);
|
_queue_page(page + j);
|
||||||
}
|
}
|
||||||
buffer_mutex->unlock();
|
buffer_mutex.unlock();
|
||||||
DEBUG_PRINT("wait");
|
DEBUG_PRINT("wait");
|
||||||
page_sem->wait();
|
page_sem->wait();
|
||||||
DEBUG_PRINT("done");
|
DEBUG_PRINT("done");
|
||||||
|
@ -436,7 +435,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||||
_queue_page(page + j);
|
_queue_page(page + j);
|
||||||
}
|
}
|
||||||
//queue pages
|
//queue pages
|
||||||
buffer_mutex->unlock();
|
buffer_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
buff = pages.write[page].buffer.ptrw();
|
buff = pages.write[page].buffer.ptrw();
|
||||||
|
@ -524,7 +523,6 @@ FileAccessNetwork::FileAccessNetwork() {
|
||||||
pos = 0;
|
pos = 0;
|
||||||
sem = SemaphoreOld::create();
|
sem = SemaphoreOld::create();
|
||||||
page_sem = SemaphoreOld::create();
|
page_sem = SemaphoreOld::create();
|
||||||
buffer_mutex = Mutex::create();
|
|
||||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||||
nc->lock_mutex();
|
nc->lock_mutex();
|
||||||
id = nc->last_id++;
|
id = nc->last_id++;
|
||||||
|
@ -542,7 +540,6 @@ FileAccessNetwork::~FileAccessNetwork() {
|
||||||
close();
|
close();
|
||||||
memdelete(sem);
|
memdelete(sem);
|
||||||
memdelete(page_sem);
|
memdelete(page_sem);
|
||||||
memdelete(buffer_mutex);
|
|
||||||
|
|
||||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||||
nc->lock_mutex();
|
nc->lock_mutex();
|
||||||
|
|
|
@ -52,8 +52,8 @@ class FileAccessNetworkClient {
|
||||||
SemaphoreOld *sem;
|
SemaphoreOld *sem;
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
bool quit;
|
bool quit;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
Mutex *blockrequest_mutex;
|
Mutex blockrequest_mutex;
|
||||||
Map<int, FileAccessNetwork *> accesses;
|
Map<int, FileAccessNetwork *> accesses;
|
||||||
Ref<StreamPeerTCP> client;
|
Ref<StreamPeerTCP> client;
|
||||||
int last_id;
|
int last_id;
|
||||||
|
@ -87,7 +87,7 @@ class FileAccessNetwork : public FileAccess {
|
||||||
|
|
||||||
SemaphoreOld *sem;
|
SemaphoreOld *sem;
|
||||||
SemaphoreOld *page_sem;
|
SemaphoreOld *page_sem;
|
||||||
Mutex *buffer_mutex;
|
Mutex buffer_mutex;
|
||||||
bool opened;
|
bool opened;
|
||||||
size_t total_size;
|
size_t total_size;
|
||||||
mutable size_t pos;
|
mutable size_t pos;
|
||||||
|
|
|
@ -70,7 +70,7 @@ struct _IP_ResolverPrivate {
|
||||||
return IP::RESOLVER_INVALID_ID;
|
return IP::RESOLVER_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
SemaphoreOld *sem;
|
SemaphoreOld *sem;
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
|
@ -100,9 +100,8 @@ struct _IP_ResolverPrivate {
|
||||||
|
|
||||||
ipr->sem->wait();
|
ipr->sem->wait();
|
||||||
|
|
||||||
ipr->mutex->lock();
|
MutexLock lock(ipr->mutex);
|
||||||
ipr->resolve_queues();
|
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) {
|
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);
|
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
||||||
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
|
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
|
||||||
IP_Address res = resolver->cache[key];
|
IP_Address res = resolver->cache[key];
|
||||||
resolver->mutex->unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Address res = _resolve_hostname(p_hostname, p_type);
|
IP_Address res = _resolve_hostname(p_hostname, p_type);
|
||||||
resolver->cache[key] = res;
|
resolver->cache[key] = res;
|
||||||
resolver->mutex->unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
|
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();
|
ResolverID id = resolver->find_empty_id();
|
||||||
|
|
||||||
if (id == RESOLVER_INVALID_ID) {
|
if (id == RESOLVER_INVALID_ID) {
|
||||||
WARN_PRINT("Out of resolver queries");
|
WARN_PRINT("Out of resolver queries");
|
||||||
resolver->mutex->unlock();
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +153,6 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
|
||||||
resolver->resolve_queues();
|
resolver->resolve_queues();
|
||||||
}
|
}
|
||||||
|
|
||||||
resolver->mutex->unlock();
|
|
||||||
return id;
|
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);
|
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) {
|
if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) {
|
||||||
ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
|
ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
|
||||||
resolver->mutex->unlock();
|
resolver->mutex.unlock();
|
||||||
return IP::RESOLVER_STATUS_NONE;
|
return IP::RESOLVER_STATUS_NONE;
|
||||||
}
|
}
|
||||||
IP::ResolverStatus res = resolver->queue[p_id].status;
|
return resolver->queue[p_id].status;
|
||||||
|
|
||||||
resolver->mutex->unlock();
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
|
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
|
||||||
|
|
||||||
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
|
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) {
|
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
|
||||||
ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
|
ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
|
||||||
resolver->mutex->unlock();
|
resolver->mutex.unlock();
|
||||||
return IP_Address();
|
return IP_Address();
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Address res = resolver->queue[p_id].response;
|
return resolver->queue[p_id].response;
|
||||||
|
|
||||||
resolver->mutex->unlock();
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IP::erase_resolve_item(ResolverID p_id) {
|
void IP::erase_resolve_item(ResolverID p_id) {
|
||||||
|
|
||||||
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
|
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->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
|
||||||
|
|
||||||
resolver->mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IP::clear_cache(const String &p_hostname) {
|
void IP::clear_cache(const String &p_hostname) {
|
||||||
|
|
||||||
resolver->mutex->lock();
|
MutexLock lock(resolver->mutex);
|
||||||
|
|
||||||
if (p_hostname.empty()) {
|
if (p_hostname.empty()) {
|
||||||
resolver->cache.clear();
|
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_IPV6));
|
||||||
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY));
|
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY));
|
||||||
}
|
}
|
||||||
|
|
||||||
resolver->mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Array IP::_get_local_addresses() const {
|
Array IP::_get_local_addresses() const {
|
||||||
|
@ -315,7 +301,6 @@ IP::IP() {
|
||||||
singleton = this;
|
singleton = this;
|
||||||
resolver = memnew(_IP_ResolverPrivate);
|
resolver = memnew(_IP_ResolverPrivate);
|
||||||
resolver->sem = NULL;
|
resolver->sem = NULL;
|
||||||
resolver->mutex = Mutex::create();
|
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
#ifndef NO_THREADS
|
||||||
|
|
||||||
|
@ -349,6 +334,5 @@ IP::~IP() {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memdelete(resolver->mutex);
|
|
||||||
memdelete(resolver);
|
memdelete(resolver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ResourceLoader::_add_to_loading_map(const String &p_path) {
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
if (loading_map_mutex) {
|
MutexLock lock(loading_map_mutex);
|
||||||
loading_map_mutex->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingMapKey key;
|
LoadingMapKey key;
|
||||||
key.path = p_path;
|
key.path = p_path;
|
||||||
|
@ -303,43 +301,27 @@ bool ResourceLoader::_add_to_loading_map(const String &p_path) {
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading_map_mutex) {
|
|
||||||
loading_map_mutex->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceLoader::_remove_from_loading_map(const String &p_path) {
|
void ResourceLoader::_remove_from_loading_map(const String &p_path) {
|
||||||
if (loading_map_mutex) {
|
MutexLock lock(loading_map_mutex);
|
||||||
loading_map_mutex->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingMapKey key;
|
LoadingMapKey key;
|
||||||
key.path = p_path;
|
key.path = p_path;
|
||||||
key.thread = Thread::get_caller_id();
|
key.thread = Thread::get_caller_id();
|
||||||
|
|
||||||
loading_map.erase(key);
|
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) {
|
void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) {
|
||||||
if (loading_map_mutex) {
|
MutexLock lock(loading_map_mutex);
|
||||||
loading_map_mutex->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingMapKey key;
|
LoadingMapKey key;
|
||||||
key.path = p_path;
|
key.path = p_path;
|
||||||
key.thread = p_thread;
|
key.thread = p_thread;
|
||||||
|
|
||||||
loading_map.erase(key);
|
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) {
|
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;
|
HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map;
|
||||||
|
|
||||||
void ResourceLoader::initialize() {
|
void ResourceLoader::initialize() {
|
||||||
#ifndef NO_THREADS
|
|
||||||
loading_map_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceLoader::finalize() {
|
void ResourceLoader::finalize() {
|
||||||
|
@ -1018,8 +997,6 @@ void ResourceLoader::finalize() {
|
||||||
ERR_PRINT("Exited while resource is being loaded: " + K->path);
|
ERR_PRINT("Exited while resource is being loaded: " + K->path);
|
||||||
}
|
}
|
||||||
loading_map.clear();
|
loading_map.clear();
|
||||||
memdelete(loading_map_mutex);
|
|
||||||
loading_map_mutex = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ class ResourceLoader {
|
||||||
static ResourceLoadedCallback _loaded_callback;
|
static ResourceLoadedCallback _loaded_callback;
|
||||||
|
|
||||||
static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
|
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
|
//used to track paths being loaded in a thread, avoids cyclic recursion
|
||||||
struct LoadingMapKey {
|
struct LoadingMapKey {
|
||||||
|
|
|
@ -30,31 +30,17 @@
|
||||||
|
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
static Mutex _global_mutex;
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
Mutex *(*Mutex::create_func)(bool) = 0;
|
|
||||||
|
|
||||||
Mutex *Mutex::create(bool p_recursive) {
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!create_func, 0);
|
|
||||||
|
|
||||||
return create_func(p_recursive);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex::~Mutex() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex *_global_mutex = NULL;
|
|
||||||
|
|
||||||
void _global_lock() {
|
void _global_lock() {
|
||||||
|
_global_mutex.lock();
|
||||||
if (_global_mutex)
|
|
||||||
_global_mutex->lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _global_unlock() {
|
void _global_unlock() {
|
||||||
|
_global_mutex.unlock();
|
||||||
if (_global_mutex)
|
|
||||||
_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> >;
|
||||||
|
|
|
@ -32,42 +32,69 @@
|
||||||
#define MUTEX_H
|
#define MUTEX_H
|
||||||
|
|
||||||
#include "core/error_list.h"
|
#include "core/error_list.h"
|
||||||
|
#include "core/typedefs.h"
|
||||||
|
|
||||||
/**
|
#if !(defined NO_THREADS)
|
||||||
* @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 );
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Mutex {
|
#include <mutex>
|
||||||
protected:
|
|
||||||
static Mutex *(*create_func)(bool);
|
template <class StdMutexT>
|
||||||
|
class MutexImpl {
|
||||||
|
mutable StdMutexT mutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void lock() = 0; ///< Lock the mutex, block if locked by someone else
|
_ALWAYS_INLINE_ void lock() const {
|
||||||
virtual void unlock() = 0; ///< Unlock the mutex, let other threads continue
|
mutex.lock();
|
||||||
virtual Error try_lock() = 0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't 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 {
|
class MutexLock {
|
||||||
|
const MutexT &mutex;
|
||||||
Mutex *mutex;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MutexLock(Mutex *p_mutex) {
|
_ALWAYS_INLINE_ explicit MutexLock(const MutexT &p_mutex) :
|
||||||
mutex = p_mutex;
|
mutex(p_mutex) {
|
||||||
if (mutex) mutex->lock();
|
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
|
#endif
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
class Mutex;
|
|
||||||
|
|
||||||
class OS {
|
class OS {
|
||||||
|
|
||||||
static OS *singleton;
|
static OS *singleton;
|
||||||
|
|
|
@ -40,14 +40,6 @@ void ThreadDummy::make_default() {
|
||||||
Thread::create_func = &ThreadDummy::create;
|
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() {
|
SemaphoreOld *SemaphoreDummy::create() {
|
||||||
return memnew(SemaphoreDummy);
|
return memnew(SemaphoreDummy);
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#ifndef THREAD_DUMMY_H
|
#ifndef THREAD_DUMMY_H
|
||||||
#define THREAD_DUMMY_H
|
#define THREAD_DUMMY_H
|
||||||
|
|
||||||
#include "core/os/mutex.h"
|
|
||||||
#include "core/os/rw_lock.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"
|
||||||
|
@ -46,18 +45,6 @@ public:
|
||||||
static void make_default();
|
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 {
|
class SemaphoreDummy : public SemaphoreOld {
|
||||||
|
|
||||||
static SemaphoreOld *create();
|
static SemaphoreOld *create();
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -33,50 +33,9 @@
|
||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
|
|
||||||
class ThreadSafe {
|
#define _THREAD_SAFE_CLASS_ mutable Mutex _thread_safe_;
|
||||||
|
#define _THREAD_SAFE_METHOD_ MutexLock _thread_safe_method_(_thread_safe_);
|
||||||
Mutex *mutex;
|
#define _THREAD_SAFE_LOCK_ _thread_safe_.lock();
|
||||||
|
#define _THREAD_SAFE_UNLOCK_ _thread_safe_.unlock();
|
||||||
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
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -90,7 +90,7 @@ static IP *ip = NULL;
|
||||||
|
|
||||||
static _Geometry *_geometry = NULL;
|
static _Geometry *_geometry = NULL;
|
||||||
|
|
||||||
extern Mutex *_global_mutex;
|
extern Mutex _global_mutex;
|
||||||
|
|
||||||
extern void register_global_constants();
|
extern void register_global_constants();
|
||||||
extern void unregister_global_constants();
|
extern void unregister_global_constants();
|
||||||
|
@ -105,8 +105,6 @@ void register_core_types() {
|
||||||
ObjectDB::setup();
|
ObjectDB::setup();
|
||||||
ResourceCache::setup();
|
ResourceCache::setup();
|
||||||
|
|
||||||
_global_mutex = Mutex::create();
|
|
||||||
|
|
||||||
StringName::setup();
|
StringName::setup();
|
||||||
ResourceLoader::initialize();
|
ResourceLoader::initialize();
|
||||||
|
|
||||||
|
@ -319,9 +317,4 @@ void unregister_core_types() {
|
||||||
ResourceCache::clear();
|
ResourceCache::clear();
|
||||||
CoreStringNames::free();
|
CoreStringNames::free();
|
||||||
StringName::cleanup();
|
StringName::cleanup();
|
||||||
|
|
||||||
if (_global_mutex) {
|
|
||||||
memdelete(_global_mutex);
|
|
||||||
_global_mutex = NULL; //still needed at a few places
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -601,7 +601,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
|
||||||
|
|
||||||
void ScriptDebuggerRemote::_get_output() {
|
void ScriptDebuggerRemote::_get_output() {
|
||||||
|
|
||||||
mutex->lock();
|
MutexLock lock(mutex);
|
||||||
|
|
||||||
if (output_strings.size()) {
|
if (output_strings.size()) {
|
||||||
|
|
||||||
locking = true;
|
locking = true;
|
||||||
|
@ -666,7 +667,6 @@ void ScriptDebuggerRemote::_get_output() {
|
||||||
errors.pop_front();
|
errors.pop_front();
|
||||||
locking = false;
|
locking = false;
|
||||||
}
|
}
|
||||||
mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptDebuggerRemote::line_poll() {
|
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) {
|
void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) {
|
||||||
|
|
||||||
mutex->lock();
|
MutexLock lock(mutex);
|
||||||
|
|
||||||
if (!locking && is_peer_connected()) {
|
if (!locking && is_peer_connected()) {
|
||||||
|
|
||||||
if (messages.size() >= max_messages_per_frame) {
|
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);
|
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) {
|
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++;
|
err_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex->lock();
|
MutexLock lock(mutex);
|
||||||
|
|
||||||
if (!locking && is_peer_connected()) {
|
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) {
|
void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) {
|
||||||
|
@ -1020,7 +1018,9 @@ void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string,
|
||||||
sdr->char_count += allowed_chars;
|
sdr->char_count += allowed_chars;
|
||||||
bool overflowed = sdr->char_count >= sdr->max_cps;
|
bool overflowed = sdr->char_count >= sdr->max_cps;
|
||||||
|
|
||||||
sdr->mutex->lock();
|
{
|
||||||
|
MutexLock lock(sdr->mutex);
|
||||||
|
|
||||||
if (!sdr->locking && sdr->is_peer_connected()) {
|
if (!sdr->locking && sdr->is_peer_connected()) {
|
||||||
|
|
||||||
if (overflowed)
|
if (overflowed)
|
||||||
|
@ -1032,7 +1032,7 @@ void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string,
|
||||||
sdr->output_strings.push_back("[output overflow, print less text!]");
|
sdr->output_strings.push_back("[output overflow, print less text!]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdr->mutex->unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptDebuggerRemote::request_quit() {
|
void ScriptDebuggerRemote::request_quit() {
|
||||||
|
@ -1106,7 +1106,6 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
|
||||||
last_net_bandwidth_time(0),
|
last_net_bandwidth_time(0),
|
||||||
performance(Engine::get_singleton()->get_singleton_object("Performance")),
|
performance(Engine::get_singleton()->get_singleton_object("Performance")),
|
||||||
requested_quit(false),
|
requested_quit(false),
|
||||||
mutex(Mutex::create()),
|
|
||||||
max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
|
max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
|
||||||
n_messages_dropped(0),
|
n_messages_dropped(0),
|
||||||
max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")),
|
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_print_handler(&phl);
|
||||||
remove_error_handler(&eh);
|
remove_error_handler(&eh);
|
||||||
memdelete(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ protected:
|
||||||
uint64_t last_net_bandwidth_time;
|
uint64_t last_net_bandwidth_time;
|
||||||
Object *performance;
|
Object *performance;
|
||||||
bool requested_quit;
|
bool requested_quit;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
List<String> output_strings;
|
List<String> output_strings;
|
||||||
List<Message> messages;
|
List<Message> messages;
|
||||||
|
|
|
@ -47,12 +47,10 @@ StringName _scs_create(const char *p_chr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StringName::configured = false;
|
bool StringName::configured = false;
|
||||||
Mutex *StringName::lock = NULL;
|
Mutex StringName::lock;
|
||||||
|
|
||||||
void StringName::setup() {
|
void StringName::setup() {
|
||||||
|
|
||||||
lock = Mutex::create();
|
|
||||||
|
|
||||||
ERR_FAIL_COND(configured);
|
ERR_FAIL_COND(configured);
|
||||||
for (int i = 0; i < STRING_TABLE_LEN; i++) {
|
for (int i = 0; i < STRING_TABLE_LEN; i++) {
|
||||||
|
|
||||||
|
@ -63,7 +61,7 @@ void StringName::setup() {
|
||||||
|
|
||||||
void StringName::cleanup() {
|
void StringName::cleanup() {
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
int lost_strings = 0;
|
int lost_strings = 0;
|
||||||
for (int i = 0; i < STRING_TABLE_LEN; i++) {
|
for (int i = 0; i < STRING_TABLE_LEN; i++) {
|
||||||
|
@ -87,9 +85,6 @@ void StringName::cleanup() {
|
||||||
if (lost_strings) {
|
if (lost_strings) {
|
||||||
print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit.");
|
print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit.");
|
||||||
}
|
}
|
||||||
lock->unlock();
|
|
||||||
|
|
||||||
memdelete(lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringName::unref() {
|
void StringName::unref() {
|
||||||
|
@ -98,7 +93,7 @@ void StringName::unref() {
|
||||||
|
|
||||||
if (_data && _data->refcount.unref()) {
|
if (_data && _data->refcount.unref()) {
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
if (_data->prev) {
|
if (_data->prev) {
|
||||||
_data->prev->next = _data->next;
|
_data->prev->next = _data->next;
|
||||||
|
@ -113,7 +108,6 @@ void StringName::unref() {
|
||||||
_data->next->prev = _data->prev;
|
_data->next->prev = _data->prev;
|
||||||
}
|
}
|
||||||
memdelete(_data);
|
memdelete(_data);
|
||||||
lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = NULL;
|
_data = NULL;
|
||||||
|
@ -184,7 +178,7 @@ StringName::StringName(const char *p_name) {
|
||||||
if (!p_name || p_name[0] == 0)
|
if (!p_name || p_name[0] == 0)
|
||||||
return; //empty, ignore
|
return; //empty, ignore
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
uint32_t hash = String::hash(p_name);
|
uint32_t hash = String::hash(p_name);
|
||||||
|
|
||||||
|
@ -203,7 +197,6 @@ StringName::StringName(const char *p_name) {
|
||||||
if (_data) {
|
if (_data) {
|
||||||
if (_data->refcount.ref()) {
|
if (_data->refcount.ref()) {
|
||||||
// exists
|
// exists
|
||||||
lock->unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,8 +212,6 @@ StringName::StringName(const char *p_name) {
|
||||||
if (_table[idx])
|
if (_table[idx])
|
||||||
_table[idx]->prev = _data;
|
_table[idx]->prev = _data;
|
||||||
_table[idx] = _data;
|
_table[idx] = _data;
|
||||||
|
|
||||||
lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName::StringName(const StaticCString &p_static_string) {
|
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]);
|
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);
|
uint32_t hash = String::hash(p_static_string.ptr);
|
||||||
|
|
||||||
|
@ -250,7 +241,6 @@ StringName::StringName(const StaticCString &p_static_string) {
|
||||||
if (_data) {
|
if (_data) {
|
||||||
if (_data->refcount.ref()) {
|
if (_data->refcount.ref()) {
|
||||||
// exists
|
// exists
|
||||||
lock->unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,8 +256,6 @@ StringName::StringName(const StaticCString &p_static_string) {
|
||||||
if (_table[idx])
|
if (_table[idx])
|
||||||
_table[idx]->prev = _data;
|
_table[idx]->prev = _data;
|
||||||
_table[idx] = _data;
|
_table[idx] = _data;
|
||||||
|
|
||||||
lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName::StringName(const String &p_name) {
|
StringName::StringName(const String &p_name) {
|
||||||
|
@ -279,10 +267,9 @@ StringName::StringName(const String &p_name) {
|
||||||
if (p_name == String())
|
if (p_name == String())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
uint32_t hash = p_name.hash();
|
uint32_t hash = p_name.hash();
|
||||||
|
|
||||||
uint32_t idx = hash & STRING_TABLE_MASK;
|
uint32_t idx = hash & STRING_TABLE_MASK;
|
||||||
|
|
||||||
_data = _table[idx];
|
_data = _table[idx];
|
||||||
|
@ -297,7 +284,6 @@ StringName::StringName(const String &p_name) {
|
||||||
if (_data) {
|
if (_data) {
|
||||||
if (_data->refcount.ref()) {
|
if (_data->refcount.ref()) {
|
||||||
// exists
|
// exists
|
||||||
lock->unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,8 +299,6 @@ StringName::StringName(const String &p_name) {
|
||||||
if (_table[idx])
|
if (_table[idx])
|
||||||
_table[idx]->prev = _data;
|
_table[idx]->prev = _data;
|
||||||
_table[idx] = _data;
|
_table[idx] = _data;
|
||||||
|
|
||||||
lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName StringName::search(const char *p_name) {
|
StringName StringName::search(const char *p_name) {
|
||||||
|
@ -325,10 +309,9 @@ StringName StringName::search(const char *p_name) {
|
||||||
if (!p_name[0])
|
if (!p_name[0])
|
||||||
return StringName();
|
return StringName();
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
uint32_t hash = String::hash(p_name);
|
uint32_t hash = String::hash(p_name);
|
||||||
|
|
||||||
uint32_t idx = hash & STRING_TABLE_MASK;
|
uint32_t idx = hash & STRING_TABLE_MASK;
|
||||||
|
|
||||||
_Data *_data = _table[idx];
|
_Data *_data = _table[idx];
|
||||||
|
@ -342,12 +325,9 @@ StringName StringName::search(const char *p_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data && _data->refcount.ref()) {
|
if (_data && _data->refcount.ref()) {
|
||||||
lock->unlock();
|
|
||||||
|
|
||||||
return StringName(_data);
|
return StringName(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock->unlock();
|
|
||||||
return StringName(); //does not exist
|
return StringName(); //does not exist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +339,7 @@ StringName StringName::search(const CharType *p_name) {
|
||||||
if (!p_name[0])
|
if (!p_name[0])
|
||||||
return StringName();
|
return StringName();
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
uint32_t hash = String::hash(p_name);
|
uint32_t hash = String::hash(p_name);
|
||||||
|
|
||||||
|
@ -376,18 +356,16 @@ StringName StringName::search(const CharType *p_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data && _data->refcount.ref()) {
|
if (_data && _data->refcount.ref()) {
|
||||||
lock->unlock();
|
|
||||||
return StringName(_data);
|
return StringName(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock->unlock();
|
|
||||||
return StringName(); //does not exist
|
return StringName(); //does not exist
|
||||||
}
|
}
|
||||||
StringName StringName::search(const String &p_name) {
|
StringName StringName::search(const String &p_name) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(p_name == "", StringName());
|
ERR_FAIL_COND_V(p_name == "", StringName());
|
||||||
|
|
||||||
lock->lock();
|
MutexLock lock(StringName::lock);
|
||||||
|
|
||||||
uint32_t hash = p_name.hash();
|
uint32_t hash = p_name.hash();
|
||||||
|
|
||||||
|
@ -404,11 +382,9 @@ StringName StringName::search(const String &p_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data && _data->refcount.ref()) {
|
if (_data && _data->refcount.ref()) {
|
||||||
lock->unlock();
|
|
||||||
return StringName(_data);
|
return StringName(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock->unlock();
|
|
||||||
return StringName(); //does not exist
|
return StringName(); //does not exist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ class StringName {
|
||||||
friend void register_core_types();
|
friend void register_core_types();
|
||||||
friend void unregister_core_types();
|
friend void unregister_core_types();
|
||||||
|
|
||||||
static Mutex *lock;
|
static Mutex lock;
|
||||||
static void setup();
|
static void setup();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
static bool configured;
|
static bool configured;
|
||||||
|
|
|
@ -154,7 +154,6 @@ Error AudioDriverALSA::init() {
|
||||||
|
|
||||||
Error err = init_device();
|
Error err = init_device();
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
mutex = Mutex::create();
|
|
||||||
thread = Thread::create(AudioDriverALSA::thread_func, this);
|
thread = Thread::create(AudioDriverALSA::thread_func, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,16 +298,16 @@ void AudioDriverALSA::set_device(String device) {
|
||||||
|
|
||||||
void AudioDriverALSA::lock() {
|
void AudioDriverALSA::lock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverALSA::unlock() {
|
void AudioDriverALSA::unlock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverALSA::finish_device() {
|
void AudioDriverALSA::finish_device() {
|
||||||
|
@ -327,11 +326,6 @@ void AudioDriverALSA::finish() {
|
||||||
|
|
||||||
memdelete(thread);
|
memdelete(thread);
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
|
||||||
if (mutex) {
|
|
||||||
memdelete(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_device();
|
finish_device();
|
||||||
|
@ -339,7 +333,6 @@ void AudioDriverALSA::finish() {
|
||||||
|
|
||||||
AudioDriverALSA::AudioDriverALSA() :
|
AudioDriverALSA::AudioDriverALSA() :
|
||||||
thread(NULL),
|
thread(NULL),
|
||||||
mutex(NULL),
|
|
||||||
pcm_handle(NULL),
|
pcm_handle(NULL),
|
||||||
device_name("Default"),
|
device_name("Default"),
|
||||||
new_device("Default") {
|
new_device("Default") {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
class AudioDriverALSA : public AudioDriver {
|
class AudioDriverALSA : public AudioDriver {
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
snd_pcm_t *pcm_handle;
|
snd_pcm_t *pcm_handle;
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,6 @@ Error MIDIDriverALSAMidi::open() {
|
||||||
}
|
}
|
||||||
snd_device_name_free_hint(hints);
|
snd_device_name_free_hint(hints);
|
||||||
|
|
||||||
mutex = Mutex::create();
|
|
||||||
exit_thread = false;
|
exit_thread = false;
|
||||||
thread = Thread::create(MIDIDriverALSAMidi::thread_func, this);
|
thread = Thread::create(MIDIDriverALSAMidi::thread_func, this);
|
||||||
|
|
||||||
|
@ -165,11 +164,6 @@ void MIDIDriverALSAMidi::close() {
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex) {
|
|
||||||
memdelete(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < connected_inputs.size(); i++) {
|
for (int i = 0; i < connected_inputs.size(); i++) {
|
||||||
snd_rawmidi_t *midi_in = connected_inputs[i];
|
snd_rawmidi_t *midi_in = connected_inputs[i];
|
||||||
snd_rawmidi_close(midi_in);
|
snd_rawmidi_close(midi_in);
|
||||||
|
@ -179,14 +173,12 @@ void MIDIDriverALSAMidi::close() {
|
||||||
|
|
||||||
void MIDIDriverALSAMidi::lock() const {
|
void MIDIDriverALSAMidi::lock() const {
|
||||||
|
|
||||||
if (mutex)
|
mutex.lock();
|
||||||
mutex->lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIDIDriverALSAMidi::unlock() const {
|
void MIDIDriverALSAMidi::unlock() const {
|
||||||
|
|
||||||
if (mutex)
|
mutex.unlock();
|
||||||
mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
|
PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
|
||||||
|
@ -210,7 +202,6 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
|
||||||
|
|
||||||
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
|
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
|
||||||
|
|
||||||
mutex = NULL;
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
|
||||||
exit_thread = false;
|
exit_thread = false;
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
class MIDIDriverALSAMidi : public MIDIDriver {
|
class MIDIDriverALSAMidi : public MIDIDriver {
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
Vector<snd_rawmidi_t *> connected_inputs;
|
Vector<snd_rawmidi_t *> connected_inputs;
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,6 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Error AudioDriverCoreAudio::init() {
|
Error AudioDriverCoreAudio::init() {
|
||||||
mutex = Mutex::create();
|
|
||||||
|
|
||||||
AudioComponentDescription desc;
|
AudioComponentDescription desc;
|
||||||
zeromem(&desc, sizeof(desc));
|
zeromem(&desc, sizeof(desc));
|
||||||
desc.componentType = kAudioUnitType_Output;
|
desc.componentType = kAudioUnitType_Output;
|
||||||
|
@ -280,19 +278,15 @@ AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const {
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioDriverCoreAudio::lock() {
|
void AudioDriverCoreAudio::lock() {
|
||||||
if (mutex)
|
mutex.lock();
|
||||||
mutex->lock();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioDriverCoreAudio::unlock() {
|
void AudioDriverCoreAudio::unlock() {
|
||||||
if (mutex)
|
mutex.unlock();
|
||||||
mutex->unlock();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool AudioDriverCoreAudio::try_lock() {
|
bool AudioDriverCoreAudio::try_lock() {
|
||||||
if (mutex)
|
return mutex.try_lock() == OK;
|
||||||
return mutex->try_lock() == OK;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverCoreAudio::finish() {
|
void AudioDriverCoreAudio::finish() {
|
||||||
|
@ -344,11 +338,6 @@ void AudioDriverCoreAudio::finish() {
|
||||||
audio_unit = NULL;
|
audio_unit = NULL;
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex) {
|
|
||||||
memdelete(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error AudioDriverCoreAudio::capture_init() {
|
Error AudioDriverCoreAudio::capture_init() {
|
||||||
|
@ -691,7 +680,6 @@ AudioDriverCoreAudio::AudioDriverCoreAudio() :
|
||||||
audio_unit(NULL),
|
audio_unit(NULL),
|
||||||
input_unit(NULL),
|
input_unit(NULL),
|
||||||
active(false),
|
active(false),
|
||||||
mutex(NULL),
|
|
||||||
device_name("Default"),
|
device_name("Default"),
|
||||||
capture_device_name("Default"),
|
capture_device_name("Default"),
|
||||||
mix_rate(0),
|
mix_rate(0),
|
||||||
|
|
|
@ -46,7 +46,7 @@ class AudioDriverCoreAudio : public AudioDriver {
|
||||||
AudioComponentInstance input_unit;
|
AudioComponentInstance input_unit;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
String device_name;
|
String device_name;
|
||||||
String capture_device_name;
|
String capture_device_name;
|
||||||
|
|
|
@ -291,7 +291,6 @@ Error AudioDriverPulseAudio::init() {
|
||||||
|
|
||||||
Error err = init_device();
|
Error err = init_device();
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
mutex = Mutex::create();
|
|
||||||
thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
|
thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,16 +596,16 @@ void AudioDriverPulseAudio::set_device(String device) {
|
||||||
|
|
||||||
void AudioDriverPulseAudio::lock() {
|
void AudioDriverPulseAudio::lock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverPulseAudio::unlock() {
|
void AudioDriverPulseAudio::unlock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverPulseAudio::finish_device() {
|
void AudioDriverPulseAudio::finish_device() {
|
||||||
|
@ -640,10 +639,6 @@ void AudioDriverPulseAudio::finish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete(thread);
|
memdelete(thread);
|
||||||
if (mutex) {
|
|
||||||
memdelete(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
}
|
}
|
||||||
|
@ -800,7 +795,6 @@ String AudioDriverPulseAudio::capture_get_device() {
|
||||||
|
|
||||||
AudioDriverPulseAudio::AudioDriverPulseAudio() :
|
AudioDriverPulseAudio::AudioDriverPulseAudio() :
|
||||||
thread(NULL),
|
thread(NULL),
|
||||||
mutex(NULL),
|
|
||||||
pa_ml(NULL),
|
pa_ml(NULL),
|
||||||
pa_ctx(NULL),
|
pa_ctx(NULL),
|
||||||
pa_str(NULL),
|
pa_str(NULL),
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
class AudioDriverPulseAudio : public AudioDriver {
|
class AudioDriverPulseAudio : public AudioDriver {
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
pa_mainloop *pa_ml;
|
pa_mainloop *pa_ml;
|
||||||
pa_context *pa_ctx;
|
pa_context *pa_ctx;
|
||||||
|
|
|
@ -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
|
|
|
@ -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 <pthread.h>
|
|
||||||
|
|
||||||
class MutexPosix : public Mutex {
|
|
||||||
|
|
||||||
pthread_mutexattr_t attr;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
|
|
||||||
static Mutex *create_func_posix(bool p_recursive);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void lock();
|
|
||||||
virtual void unlock();
|
|
||||||
virtual Error try_lock();
|
|
||||||
|
|
||||||
static void make_default();
|
|
||||||
|
|
||||||
MutexPosix(bool p_recursive);
|
|
||||||
|
|
||||||
~MutexPosix();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
#include "drivers/unix/dir_access_unix.h"
|
#include "drivers/unix/dir_access_unix.h"
|
||||||
#include "drivers/unix/file_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/net_socket_posix.h"
|
||||||
#include "drivers/unix/rw_lock_posix.h"
|
#include "drivers/unix/rw_lock_posix.h"
|
||||||
#include "drivers/unix/semaphore_posix.h"
|
#include "drivers/unix/semaphore_posix.h"
|
||||||
|
@ -123,14 +122,12 @@ void OS_Unix::initialize_core() {
|
||||||
#ifdef NO_THREADS
|
#ifdef NO_THREADS
|
||||||
ThreadDummy::make_default();
|
ThreadDummy::make_default();
|
||||||
SemaphoreDummy::make_default();
|
SemaphoreDummy::make_default();
|
||||||
MutexDummy::make_default();
|
|
||||||
RWLockDummy::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();
|
|
||||||
RWLockPosix::make_default();
|
RWLockPosix::make_default();
|
||||||
#endif
|
#endif
|
||||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
||||||
|
|
|
@ -406,7 +406,6 @@ Error AudioDriverWASAPI::init() {
|
||||||
exit_thread = false;
|
exit_thread = false;
|
||||||
thread_exited = false;
|
thread_exited = false;
|
||||||
|
|
||||||
mutex = Mutex::create(true);
|
|
||||||
thread = Thread::create(thread_func, this);
|
thread = Thread::create(thread_func, this);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -782,14 +781,12 @@ void AudioDriverWASAPI::start() {
|
||||||
|
|
||||||
void AudioDriverWASAPI::lock() {
|
void AudioDriverWASAPI::lock() {
|
||||||
|
|
||||||
if (mutex)
|
mutex.lock();
|
||||||
mutex->lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverWASAPI::unlock() {
|
void AudioDriverWASAPI::unlock() {
|
||||||
|
|
||||||
if (mutex)
|
mutex.unlock();
|
||||||
mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverWASAPI::finish() {
|
void AudioDriverWASAPI::finish() {
|
||||||
|
@ -804,11 +801,6 @@ void AudioDriverWASAPI::finish() {
|
||||||
|
|
||||||
finish_capture_device();
|
finish_capture_device();
|
||||||
finish_render_device();
|
finish_render_device();
|
||||||
|
|
||||||
if (mutex) {
|
|
||||||
memdelete(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error AudioDriverWASAPI::capture_start() {
|
Error AudioDriverWASAPI::capture_start() {
|
||||||
|
@ -863,7 +855,6 @@ String AudioDriverWASAPI::capture_get_device() {
|
||||||
|
|
||||||
AudioDriverWASAPI::AudioDriverWASAPI() {
|
AudioDriverWASAPI::AudioDriverWASAPI() {
|
||||||
|
|
||||||
mutex = NULL;
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
|
||||||
samples_in.clear();
|
samples_in.clear();
|
||||||
|
|
|
@ -75,7 +75,7 @@ class AudioDriverWASAPI : public AudioDriver {
|
||||||
AudioDeviceWASAPI audio_input;
|
AudioDeviceWASAPI audio_input;
|
||||||
AudioDeviceWASAPI audio_output;
|
AudioDeviceWASAPI audio_output;
|
||||||
|
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
|
|
||||||
Vector<int32_t> samples_in;
|
Vector<int32_t> samples_in;
|
||||||
|
|
|
@ -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
|
|
|
@ -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 <windows.h>
|
|
||||||
|
|
||||||
class MutexWindows : public Mutex {
|
|
||||||
|
|
||||||
#ifdef WINDOWS_USE_MUTEX
|
|
||||||
HANDLE mutex;
|
|
||||||
#else
|
|
||||||
CRITICAL_SECTION mutex;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static Mutex *create_func_windows(bool p_recursive);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void lock();
|
|
||||||
virtual void unlock();
|
|
||||||
virtual Error try_lock();
|
|
||||||
|
|
||||||
static void make_default();
|
|
||||||
|
|
||||||
MutexWindows();
|
|
||||||
~MutexWindows();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -79,7 +79,6 @@ Error AudioDriverXAudio2::init() {
|
||||||
hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback);
|
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) + ".");
|
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);
|
thread = Thread::create(AudioDriverXAudio2::thread_func, this);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -158,15 +157,15 @@ float AudioDriverXAudio2::get_latency() {
|
||||||
|
|
||||||
void AudioDriverXAudio2::lock() {
|
void AudioDriverXAudio2::lock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
void AudioDriverXAudio2::unlock() {
|
void AudioDriverXAudio2::unlock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverXAudio2::finish() {
|
void AudioDriverXAudio2::finish() {
|
||||||
|
@ -194,14 +193,11 @@ void AudioDriverXAudio2::finish() {
|
||||||
mastering_voice->DestroyVoice();
|
mastering_voice->DestroyVoice();
|
||||||
|
|
||||||
memdelete(thread);
|
memdelete(thread);
|
||||||
if (mutex)
|
|
||||||
memdelete(mutex);
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDriverXAudio2::AudioDriverXAudio2() :
|
AudioDriverXAudio2::AudioDriverXAudio2() :
|
||||||
thread(NULL),
|
thread(NULL),
|
||||||
mutex(NULL),
|
|
||||||
current_buffer(0) {
|
current_buffer(0) {
|
||||||
wave_format = { 0 };
|
wave_format = { 0 };
|
||||||
for (int i = 0; i < AUDIO_BUFFERS; i++) {
|
for (int i = 0; i < AUDIO_BUFFERS; i++) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ class AudioDriverXAudio2 : public AudioDriver {
|
||||||
};
|
};
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
int32_t *samples_in;
|
int32_t *samples_in;
|
||||||
int16_t *samples_out[AUDIO_BUFFERS];
|
int16_t *samples_out[AUDIO_BUFFERS];
|
||||||
|
|
|
@ -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) {
|
static void _execute_thread(void *p_ud) {
|
||||||
|
|
||||||
EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)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));
|
print_verbose("Thread exit status: " + itos(eta->exitcode));
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
eta->exitcode = err;
|
eta->exitcode = err;
|
||||||
|
@ -5574,7 +5574,6 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
|
||||||
ExecuteThreadArgs eta;
|
ExecuteThreadArgs eta;
|
||||||
eta.path = p_path;
|
eta.path = p_path;
|
||||||
eta.args = p_arguments;
|
eta.args = p_arguments;
|
||||||
eta.execute_output_mutex = Mutex::create();
|
|
||||||
eta.exitcode = 255;
|
eta.exitcode = 255;
|
||||||
eta.done = false;
|
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);
|
ERR_FAIL_COND_V(!eta.execute_output_thread, 0);
|
||||||
|
|
||||||
while (!eta.done) {
|
while (!eta.done) {
|
||||||
eta.execute_output_mutex->lock();
|
{
|
||||||
|
MutexLock lock(eta.execute_output_mutex);
|
||||||
if (prev_len != eta.output.length()) {
|
if (prev_len != eta.output.length()) {
|
||||||
String to_add = eta.output.substr(prev_len, eta.output.length());
|
String to_add = eta.output.substr(prev_len, eta.output.length());
|
||||||
prev_len = eta.output.length();
|
prev_len = eta.output.length();
|
||||||
execute_outputs->add_text(to_add);
|
execute_outputs->add_text(to_add);
|
||||||
Main::iteration();
|
Main::iteration();
|
||||||
}
|
}
|
||||||
eta.execute_output_mutex->unlock();
|
}
|
||||||
OS::get_singleton()->delay_usec(1000);
|
OS::get_singleton()->delay_usec(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::wait_to_finish(eta.execute_output_thread);
|
Thread::wait_to_finish(eta.execute_output_thread);
|
||||||
memdelete(eta.execute_output_thread);
|
memdelete(eta.execute_output_thread);
|
||||||
memdelete(eta.execute_output_mutex);
|
|
||||||
execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode));
|
execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode));
|
||||||
|
|
||||||
if (p_close_on_errors && eta.exitcode != 0) {
|
if (p_close_on_errors && eta.exitcode != 0) {
|
||||||
|
|
|
@ -107,7 +107,7 @@ public:
|
||||||
List<String> args;
|
List<String> args;
|
||||||
String output;
|
String output;
|
||||||
Thread *execute_output_thread;
|
Thread *execute_output_thread;
|
||||||
Mutex *execute_output_mutex;
|
Mutex execute_output_mutex;
|
||||||
int exitcode;
|
int exitcode;
|
||||||
volatile bool done;
|
volatile bool done;
|
||||||
};
|
};
|
||||||
|
|
|
@ -109,9 +109,9 @@ void EditorResourcePreview::_thread_func(void *ud) {
|
||||||
|
|
||||||
void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) {
|
void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) {
|
||||||
|
|
||||||
preview_mutex->lock();
|
MutexLock lock(preview_mutex);
|
||||||
|
|
||||||
String path = p_str;
|
String path = p_str;
|
||||||
|
{
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
uint64_t modified_time = 0;
|
uint64_t modified_time = 0;
|
||||||
|
|
||||||
|
@ -130,8 +130,7 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur
|
||||||
item.modified_time = modified_time;
|
item.modified_time = modified_time;
|
||||||
|
|
||||||
cache[path] = item;
|
cache[path] = item;
|
||||||
|
}
|
||||||
preview_mutex->unlock();
|
|
||||||
|
|
||||||
MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_small_texture, p_ud);
|
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) {
|
while (!exit) {
|
||||||
|
|
||||||
preview_sem->wait();
|
preview_sem->wait();
|
||||||
preview_mutex->lock();
|
preview_mutex.lock();
|
||||||
|
|
||||||
if (queue.size()) {
|
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_ready(path, cache[item.path].preview, cache[item.path].small_preview, item.id, item.function, item.userdata);
|
||||||
|
|
||||||
preview_mutex->unlock();
|
preview_mutex.unlock();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
preview_mutex->unlock();
|
preview_mutex.unlock();
|
||||||
|
|
||||||
Ref<ImageTexture> texture;
|
Ref<ImageTexture> texture;
|
||||||
Ref<ImageTexture> small_texture;
|
Ref<ImageTexture> small_texture;
|
||||||
|
@ -345,7 +344,7 @@ void EditorResourcePreview::_thread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
preview_mutex->unlock();
|
preview_mutex.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exited = true;
|
exited = true;
|
||||||
|
@ -356,7 +355,8 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
|
||||||
ERR_FAIL_NULL(p_receiver);
|
ERR_FAIL_NULL(p_receiver);
|
||||||
ERR_FAIL_COND(!p_res.is_valid());
|
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());
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
|
||||||
|
|
||||||
cache[path_id].order = order++;
|
cache[path_id].order = order++;
|
||||||
p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata);
|
p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata);
|
||||||
preview_mutex->unlock();
|
preview_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,18 +378,20 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
|
||||||
item.userdata = p_userdata;
|
item.userdata = p_userdata;
|
||||||
|
|
||||||
queue.push_back(item);
|
queue.push_back(item);
|
||||||
preview_mutex->unlock();
|
}
|
||||||
preview_sem->post();
|
preview_sem->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorResourcePreview::queue_resource_preview(const String &p_path, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) {
|
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);
|
ERR_FAIL_NULL(p_receiver);
|
||||||
preview_mutex->lock();
|
{
|
||||||
|
MutexLock lock(preview_mutex);
|
||||||
|
|
||||||
if (cache.has(p_path)) {
|
if (cache.has(p_path)) {
|
||||||
cache[p_path].order = order++;
|
cache[p_path].order = order++;
|
||||||
p_receiver->call(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata);
|
p_receiver->call(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata);
|
||||||
preview_mutex->unlock();
|
preview_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +402,7 @@ void EditorResourcePreview::queue_resource_preview(const String &p_path, Object
|
||||||
item.userdata = p_userdata;
|
item.userdata = p_userdata;
|
||||||
|
|
||||||
queue.push_back(item);
|
queue.push_back(item);
|
||||||
preview_mutex->unlock();
|
}
|
||||||
preview_sem->post();
|
preview_sem->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,9 +436,9 @@ void EditorResourcePreview::_bind_methods() {
|
||||||
|
|
||||||
void EditorResourcePreview::check_for_invalidation(const String &p_path) {
|
void EditorResourcePreview::check_for_invalidation(const String &p_path) {
|
||||||
|
|
||||||
preview_mutex->lock();
|
MutexLock lock(preview_mutex);
|
||||||
|
|
||||||
bool call_invalidated = false;
|
bool call_invalidated = false;
|
||||||
|
{
|
||||||
if (cache.has(p_path)) {
|
if (cache.has(p_path)) {
|
||||||
|
|
||||||
uint64_t modified_time = FileAccess::get_modified_time(p_path);
|
uint64_t modified_time = FileAccess::get_modified_time(p_path);
|
||||||
|
@ -445,8 +447,7 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) {
|
||||||
call_invalidated = true;
|
call_invalidated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
preview_mutex->unlock();
|
|
||||||
|
|
||||||
if (call_invalidated) { //do outside mutex
|
if (call_invalidated) { //do outside mutex
|
||||||
call_deferred("emit_signal", "preview_invalidated", p_path);
|
call_deferred("emit_signal", "preview_invalidated", p_path);
|
||||||
|
@ -475,7 +476,6 @@ void EditorResourcePreview::stop() {
|
||||||
EditorResourcePreview::EditorResourcePreview() {
|
EditorResourcePreview::EditorResourcePreview() {
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
singleton = this;
|
singleton = this;
|
||||||
preview_mutex = Mutex::create();
|
|
||||||
preview_sem = SemaphoreOld::create();
|
preview_sem = SemaphoreOld::create();
|
||||||
order = 0;
|
order = 0;
|
||||||
exit = false;
|
exit = false;
|
||||||
|
@ -485,6 +485,5 @@ EditorResourcePreview::EditorResourcePreview() {
|
||||||
EditorResourcePreview::~EditorResourcePreview() {
|
EditorResourcePreview::~EditorResourcePreview() {
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
memdelete(preview_mutex);
|
|
||||||
memdelete(preview_sem);
|
memdelete(preview_sem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ class EditorResourcePreview : public Node {
|
||||||
|
|
||||||
List<QueueItem> queue;
|
List<QueueItem> queue;
|
||||||
|
|
||||||
Mutex *preview_mutex;
|
Mutex preview_mutex;
|
||||||
SemaphoreOld *preview_sem;
|
SemaphoreOld *preview_sem;
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
volatile bool exit;
|
volatile bool exit;
|
||||||
|
|
|
@ -42,9 +42,10 @@
|
||||||
void EditorFileServer::_close_client(ClientData *cd) {
|
void EditorFileServer::_close_client(ClientData *cd) {
|
||||||
|
|
||||||
cd->connection->disconnect_from_host();
|
cd->connection->disconnect_from_host();
|
||||||
cd->efs->wait_mutex->lock();
|
{
|
||||||
|
MutexLock lock(cd->efs->wait_mutex);
|
||||||
cd->efs->to_wait.insert(cd->thread);
|
cd->efs->to_wait.insert(cd->thread);
|
||||||
cd->efs->wait_mutex->unlock();
|
}
|
||||||
while (cd->files.size()) {
|
while (cd->files.size()) {
|
||||||
memdelete(cd->files.front()->get());
|
memdelete(cd->files.front()->get());
|
||||||
cd->files.erase(cd->files.front());
|
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()) {
|
while (self->to_wait.size()) {
|
||||||
Thread *w = self->to_wait.front()->get();
|
Thread *w = self->to_wait.front()->get();
|
||||||
self->to_wait.erase(w);
|
self->to_wait.erase(w);
|
||||||
self->wait_mutex->unlock();
|
self->wait_mutex.unlock();
|
||||||
Thread::wait_to_finish(w);
|
Thread::wait_to_finish(w);
|
||||||
memdelete(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);
|
OS::get_singleton()->delay_usec(100000);
|
||||||
}
|
}
|
||||||
|
@ -331,7 +332,6 @@ void EditorFileServer::stop() {
|
||||||
EditorFileServer::EditorFileServer() {
|
EditorFileServer::EditorFileServer() {
|
||||||
|
|
||||||
server.instance();
|
server.instance();
|
||||||
wait_mutex = Mutex::create();
|
|
||||||
quit = false;
|
quit = false;
|
||||||
active = false;
|
active = false;
|
||||||
cmd = CMD_NONE;
|
cmd = CMD_NONE;
|
||||||
|
@ -346,5 +346,4 @@ EditorFileServer::~EditorFileServer() {
|
||||||
quit = true;
|
quit = true;
|
||||||
Thread::wait_to_finish(thread);
|
Thread::wait_to_finish(thread);
|
||||||
memdelete(thread);
|
memdelete(thread);
|
||||||
memdelete(wait_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ class EditorFileServer : public Object {
|
||||||
static void _close_client(ClientData *cd);
|
static void _close_client(ClientData *cd);
|
||||||
static void _subthread_start(void *s);
|
static void _subthread_start(void *s);
|
||||||
|
|
||||||
Mutex *wait_mutex;
|
Mutex wait_mutex;
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
static void _thread_start(void *);
|
static void _thread_start(void *);
|
||||||
bool quit;
|
bool quit;
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
|
|
||||||
void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_channel) {
|
void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_channel) {
|
||||||
|
|
||||||
singleton->mutex->lock();
|
MutexLock lock(singleton->mutex);
|
||||||
|
|
||||||
StringName path = p_tex->get_path();
|
StringName path = p_tex->get_path();
|
||||||
|
|
||||||
if (!singleton->make_flags.has(path)) {
|
if (!singleton->make_flags.has(path)) {
|
||||||
|
@ -48,13 +49,12 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTextur
|
||||||
singleton->make_flags[path].flags |= MAKE_ROUGHNESS_FLAG;
|
singleton->make_flags[path].flags |= MAKE_ROUGHNESS_FLAG;
|
||||||
singleton->make_flags[path].channel_for_roughness = p_channel;
|
singleton->make_flags[path].channel_for_roughness = p_channel;
|
||||||
singleton->make_flags[path].normal_path_for_roughness = p_normal_path;
|
singleton->make_flags[path].normal_path_for_roughness = p_normal_path;
|
||||||
|
|
||||||
singleton->mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) {
|
void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) {
|
||||||
|
|
||||||
singleton->mutex->lock();
|
MutexLock lock(singleton->mutex);
|
||||||
|
|
||||||
StringName path = p_tex->get_path();
|
StringName path = p_tex->get_path();
|
||||||
|
|
||||||
if (!singleton->make_flags.has(path)) {
|
if (!singleton->make_flags.has(path)) {
|
||||||
|
@ -62,13 +62,12 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_t
|
||||||
}
|
}
|
||||||
|
|
||||||
singleton->make_flags[path].flags |= MAKE_3D_FLAG;
|
singleton->make_flags[path].flags |= MAKE_3D_FLAG;
|
||||||
|
|
||||||
singleton->mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) {
|
void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) {
|
||||||
|
|
||||||
singleton->mutex->lock();
|
MutexLock lock(singleton->mutex);
|
||||||
|
|
||||||
StringName path = p_tex->get_path();
|
StringName path = p_tex->get_path();
|
||||||
|
|
||||||
if (!singleton->make_flags.has(path)) {
|
if (!singleton->make_flags.has(path)) {
|
||||||
|
@ -76,8 +75,6 @@ void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture>
|
||||||
}
|
}
|
||||||
|
|
||||||
singleton->make_flags[path].flags |= MAKE_NORMAL_FLAG;
|
singleton->make_flags[path].flags |= MAKE_NORMAL_FLAG;
|
||||||
|
|
||||||
singleton->mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceImporterTexture::update_imports() {
|
void ResourceImporterTexture::update_imports() {
|
||||||
|
@ -85,14 +82,14 @@ void ResourceImporterTexture::update_imports() {
|
||||||
if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) {
|
if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) {
|
||||||
return; // do nothing for now
|
return; // do nothing for now
|
||||||
}
|
}
|
||||||
mutex->lock();
|
|
||||||
|
|
||||||
|
MutexLock lock(mutex);
|
||||||
|
Vector<String> to_reimport;
|
||||||
|
{
|
||||||
if (make_flags.empty()) {
|
if (make_flags.empty()) {
|
||||||
mutex->unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> to_reimport;
|
|
||||||
for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) {
|
for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Ref<ConfigFile> cf;
|
Ref<ConfigFile> cf;
|
||||||
|
@ -134,8 +131,7 @@ void ResourceImporterTexture::update_imports() {
|
||||||
}
|
}
|
||||||
|
|
||||||
make_flags.clear();
|
make_flags.clear();
|
||||||
|
}
|
||||||
mutex->unlock();
|
|
||||||
|
|
||||||
if (to_reimport.size()) {
|
if (to_reimport.size()) {
|
||||||
EditorFileSystem::get_singleton()->reimport_files(to_reimport);
|
EditorFileSystem::get_singleton()->reimport_files(to_reimport);
|
||||||
|
@ -642,10 +638,7 @@ ResourceImporterTexture::ResourceImporterTexture() {
|
||||||
StreamTexture::request_3d_callback = _texture_reimport_3d;
|
StreamTexture::request_3d_callback = _texture_reimport_3d;
|
||||||
StreamTexture::request_roughness_callback = _texture_reimport_roughness;
|
StreamTexture::request_roughness_callback = _texture_reimport_roughness;
|
||||||
StreamTexture::request_normal_callback = _texture_reimport_normal;
|
StreamTexture::request_normal_callback = _texture_reimport_normal;
|
||||||
mutex = Mutex::create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceImporterTexture::~ResourceImporterTexture() {
|
ResourceImporterTexture::~ResourceImporterTexture() {
|
||||||
|
|
||||||
memdelete(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ protected:
|
||||||
MAKE_NORMAL_FLAG = 4
|
MAKE_NORMAL_FLAG = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
struct MakeInfo {
|
struct MakeInfo {
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
|
|
|
@ -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);
|
nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
{
|
||||||
owners_lock->lock();
|
MutexLock lock(owners_lock);
|
||||||
#endif
|
|
||||||
|
|
||||||
instance_owners.insert(p_this);
|
instance_owners.insert(p_this);
|
||||||
|
}
|
||||||
#ifndef NO_THREADS
|
|
||||||
owners_lock->unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return nsi;
|
return nsi;
|
||||||
}
|
}
|
||||||
|
@ -782,17 +778,10 @@ NativeScript::NativeScript() {
|
||||||
library = Ref<GDNative>();
|
library = Ref<GDNative>();
|
||||||
lib_path = "";
|
lib_path = "";
|
||||||
class_name = "";
|
class_name = "";
|
||||||
#ifndef NO_THREADS
|
|
||||||
owners_lock = Mutex::create();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeScript::~NativeScript() {
|
NativeScript::~NativeScript() {
|
||||||
NSL->unregister_script(this);
|
NSL->unregister_script(this);
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(owners_lock);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_SCRIPT_DESC() script->get_script_desc()
|
#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);
|
script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata);
|
||||||
|
|
||||||
if (owner) {
|
if (owner) {
|
||||||
|
MutexLock lock(script->owners_lock);
|
||||||
#ifndef NO_THREADS
|
|
||||||
script->owners_lock->lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
script->instance_owners.erase(owner);
|
script->instance_owners.erase(owner);
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
script->owners_lock->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,7 +1228,6 @@ NativeScriptLanguage::NativeScriptLanguage() {
|
||||||
NativeScriptLanguage::singleton = this;
|
NativeScriptLanguage::singleton = this;
|
||||||
#ifndef NO_THREADS
|
#ifndef NO_THREADS
|
||||||
has_objects_to_register = false;
|
has_objects_to_register = false;
|
||||||
mutex = Mutex::create();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
@ -1283,10 +1264,6 @@ NativeScriptLanguage::~NativeScriptLanguage() {
|
||||||
NSL->library_classes.clear();
|
NSL->library_classes.clear();
|
||||||
NSL->library_gdnatives.clear();
|
NSL->library_gdnatives.clear();
|
||||||
NSL->library_script_users.clear();
|
NSL->library_script_users.clear();
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(mutex);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String NativeScriptLanguage::get_name() const {
|
String NativeScriptLanguage::get_name() const {
|
||||||
|
@ -1413,9 +1390,7 @@ void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_
|
||||||
|
|
||||||
void NativeScriptLanguage::profiling_start() {
|
void NativeScriptLanguage::profiling_start() {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
|
|
||||||
profile_data.clear();
|
profile_data.clear();
|
||||||
profiling = true;
|
profiling = true;
|
||||||
|
@ -1424,9 +1399,7 @@ void NativeScriptLanguage::profiling_start() {
|
||||||
|
|
||||||
void NativeScriptLanguage::profiling_stop() {
|
void NativeScriptLanguage::profiling_stop() {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
|
|
||||||
profiling = false;
|
profiling = false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1434,9 +1407,8 @@ void NativeScriptLanguage::profiling_stop() {
|
||||||
|
|
||||||
int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
|
int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
int current = 0;
|
int current = 0;
|
||||||
|
|
||||||
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
|
for (Map<StringName, ProfileData>::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) {
|
int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
int current = 0;
|
int current = 0;
|
||||||
|
|
||||||
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
|
for (Map<StringName, ProfileData>::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) {
|
void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
|
|
||||||
Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature);
|
Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature);
|
||||||
if (d) {
|
if (d) {
|
||||||
|
@ -1705,9 +1674,8 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
|
void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
// See if this library was "registered" already.
|
// See if this library was "registered" already.
|
||||||
const String &lib_path = lib->get_current_library_path();
|
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.");
|
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<GDNativeLibrary> &lib) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeScriptLanguage::register_script(NativeScript *script) {
|
void NativeScriptLanguage::register_script(NativeScript *script) {
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
library_script_users[script->lib_path].insert(script);
|
library_script_users[script->lib_path].insert(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeScriptLanguage::unregister_script(NativeScript *script) {
|
void NativeScriptLanguage::unregister_script(NativeScript *script) {
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
Map<String, Set<NativeScript *> >::Element *S = library_script_users.find(script->lib_path);
|
Map<String, Set<NativeScript *> >::Element *S = library_script_users.find(script->lib_path);
|
||||||
if (S) {
|
if (S) {
|
||||||
S->get().erase(script);
|
S->get().erase(script);
|
||||||
|
@ -1803,9 +1769,7 @@ void NativeScriptLanguage::frame() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
{
|
{
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(mutex);
|
MutexLock lock(mutex);
|
||||||
#endif
|
|
||||||
|
|
||||||
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
|
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
|
||||||
d->get().last_frame_call_count = d->get().frame_call_count;
|
d->get().last_frame_call_count = d->get().frame_call_count;
|
||||||
|
@ -1867,9 +1831,7 @@ void NativeReloadNode::_notification(int p_what) {
|
||||||
|
|
||||||
if (unloaded)
|
if (unloaded)
|
||||||
break;
|
break;
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(NSL->mutex);
|
MutexLock lock(NSL->mutex);
|
||||||
#endif
|
|
||||||
NSL->_unload_stuff(true);
|
NSL->_unload_stuff(true);
|
||||||
|
|
||||||
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
|
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
|
||||||
|
@ -1904,9 +1866,8 @@ void NativeReloadNode::_notification(int p_what) {
|
||||||
|
|
||||||
if (!unloaded)
|
if (!unloaded)
|
||||||
break;
|
break;
|
||||||
#ifndef NO_THREADS
|
|
||||||
MutexLock lock(NSL->mutex);
|
MutexLock lock(NSL->mutex);
|
||||||
#endif
|
|
||||||
Set<StringName> libs_to_remove;
|
Set<StringName> libs_to_remove;
|
||||||
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
|
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "core/io/resource_saver.h"
|
#include "core/io/resource_saver.h"
|
||||||
#include "core/oa_hash_map.h"
|
#include "core/oa_hash_map.h"
|
||||||
#include "core/ordered_hash_map.h"
|
#include "core/ordered_hash_map.h"
|
||||||
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread_safe.h"
|
#include "core/os/thread_safe.h"
|
||||||
#include "core/resource.h"
|
#include "core/resource.h"
|
||||||
#include "core/script_language.h"
|
#include "core/script_language.h"
|
||||||
|
@ -44,10 +45,6 @@
|
||||||
#include "modules/gdnative/gdnative.h"
|
#include "modules/gdnative/gdnative.h"
|
||||||
#include <nativescript/godot_nativescript.h>
|
#include <nativescript/godot_nativescript.h>
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
#include "core/os/mutex.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct NativeScriptDesc {
|
struct NativeScriptDesc {
|
||||||
|
|
||||||
struct Method {
|
struct Method {
|
||||||
|
@ -127,9 +124,7 @@ class NativeScript : public Script {
|
||||||
String script_class_name;
|
String script_class_name;
|
||||||
String script_class_icon_path;
|
String script_class_icon_path;
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
Mutex owners_lock;
|
||||||
Mutex *owners_lock;
|
|
||||||
#endif
|
|
||||||
Set<Object *> instance_owners;
|
Set<Object *> instance_owners;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -266,9 +261,8 @@ private:
|
||||||
|
|
||||||
void _unload_stuff(bool p_reload = false);
|
void _unload_stuff(bool p_reload = false);
|
||||||
|
|
||||||
|
Mutex mutex;
|
||||||
#ifndef NO_THREADS
|
#ifndef NO_THREADS
|
||||||
Mutex *mutex;
|
|
||||||
|
|
||||||
Set<Ref<GDNativeLibrary> > libs_to_init;
|
Set<Ref<GDNativeLibrary> > libs_to_init;
|
||||||
Set<NativeScript *> scripts_to_register;
|
Set<NativeScript *> scripts_to_register;
|
||||||
volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed
|
volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed
|
||||||
|
|
|
@ -399,39 +399,18 @@ void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginScriptLanguage::lock() {
|
void PluginScriptLanguage::lock() {
|
||||||
#ifndef NO_THREADS
|
_lock.lock();
|
||||||
if (_lock) {
|
|
||||||
_lock->lock();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginScriptLanguage::unlock() {
|
void PluginScriptLanguage::unlock() {
|
||||||
#ifndef NO_THREADS
|
_lock.unlock();
|
||||||
if (_lock) {
|
|
||||||
_lock->unlock();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) :
|
PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) :
|
||||||
_desc(*desc) {
|
_desc(*desc) {
|
||||||
_resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this)));
|
_resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this)));
|
||||||
_resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this)));
|
_resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this)));
|
||||||
|
|
||||||
// TODO: totally remove _lock attribute if NO_THREADS is set
|
|
||||||
#ifdef NO_THREADS
|
|
||||||
_lock = NULL;
|
|
||||||
#else
|
|
||||||
_lock = Mutex::create();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginScriptLanguage::~PluginScriptLanguage() {
|
PluginScriptLanguage::~PluginScriptLanguage() {
|
||||||
#ifndef NO_THREADS
|
|
||||||
if (_lock) {
|
|
||||||
memdelete(_lock);
|
|
||||||
_lock = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ class PluginScriptLanguage : public ScriptLanguage {
|
||||||
const godot_pluginscript_language_desc _desc;
|
const godot_pluginscript_language_desc _desc;
|
||||||
godot_pluginscript_language_data *_data;
|
godot_pluginscript_language_data *_data;
|
||||||
|
|
||||||
Mutex *_lock;
|
Mutex _lock;
|
||||||
SelfList<PluginScript>::List _script_list;
|
SelfList<PluginScript>::List _script_list;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -115,31 +115,27 @@
|
||||||
|
|
||||||
GdNavigationServer::GdNavigationServer() :
|
GdNavigationServer::GdNavigationServer() :
|
||||||
NavigationServer(),
|
NavigationServer(),
|
||||||
commands_mutex(Mutex::create()),
|
|
||||||
operations_mutex(Mutex::create()),
|
|
||||||
active(true) {
|
active(true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GdNavigationServer::~GdNavigationServer() {
|
GdNavigationServer::~GdNavigationServer() {
|
||||||
flush_queries();
|
flush_queries();
|
||||||
memdelete(operations_mutex);
|
|
||||||
memdelete(commands_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdNavigationServer::add_command(SetCommand *command) const {
|
void GdNavigationServer::add_command(SetCommand *command) const {
|
||||||
auto mut_this = const_cast<GdNavigationServer *>(this);
|
auto mut_this = const_cast<GdNavigationServer *>(this);
|
||||||
commands_mutex->lock();
|
{
|
||||||
|
MutexLock lock(commands_mutex);
|
||||||
mut_this->commands.push_back(command);
|
mut_this->commands.push_back(command);
|
||||||
commands_mutex->unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RID GdNavigationServer::map_create() const {
|
RID GdNavigationServer::map_create() const {
|
||||||
auto mut_this = const_cast<GdNavigationServer *>(this);
|
auto mut_this = const_cast<GdNavigationServer *>(this);
|
||||||
mut_this->operations_mutex->lock();
|
MutexLock lock(mut_this->operations_mutex);
|
||||||
NavMap *space = memnew(NavMap);
|
NavMap *space = memnew(NavMap);
|
||||||
RID rid = map_owner.make_rid(space);
|
RID rid = map_owner.make_rid(space);
|
||||||
space->set_self(rid);
|
space->set_self(rid);
|
||||||
mut_this->operations_mutex->unlock();
|
|
||||||
return rid;
|
return rid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,11 +238,10 @@ RID GdNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_
|
||||||
|
|
||||||
RID GdNavigationServer::region_create() const {
|
RID GdNavigationServer::region_create() const {
|
||||||
auto mut_this = const_cast<GdNavigationServer *>(this);
|
auto mut_this = const_cast<GdNavigationServer *>(this);
|
||||||
mut_this->operations_mutex->lock();
|
MutexLock lock(mut_this->operations_mutex);
|
||||||
NavRegion *reg = memnew(NavRegion);
|
NavRegion *reg = memnew(NavRegion);
|
||||||
RID rid = region_owner.make_rid(reg);
|
RID rid = region_owner.make_rid(reg);
|
||||||
reg->set_self(rid);
|
reg->set_self(rid);
|
||||||
mut_this->operations_mutex->unlock();
|
|
||||||
return rid;
|
return rid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,11 +293,10 @@ void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p
|
||||||
|
|
||||||
RID GdNavigationServer::agent_create() const {
|
RID GdNavigationServer::agent_create() const {
|
||||||
auto mut_this = const_cast<GdNavigationServer *>(this);
|
auto mut_this = const_cast<GdNavigationServer *>(this);
|
||||||
mut_this->operations_mutex->lock();
|
MutexLock lock(mut_this->operations_mutex);
|
||||||
RvoAgent *agent = memnew(RvoAgent());
|
RvoAgent *agent = memnew(RvoAgent());
|
||||||
RID rid = agent_owner.make_rid(agent);
|
RID rid = agent_owner.make_rid(agent);
|
||||||
agent->set_self(rid);
|
agent->set_self(rid);
|
||||||
mut_this->operations_mutex->unlock();
|
|
||||||
return rid;
|
return rid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,23 +464,20 @@ COMMAND_1(free, RID, p_object) {
|
||||||
|
|
||||||
void GdNavigationServer::set_active(bool p_active) const {
|
void GdNavigationServer::set_active(bool p_active) const {
|
||||||
auto mut_this = const_cast<GdNavigationServer *>(this);
|
auto mut_this = const_cast<GdNavigationServer *>(this);
|
||||||
mut_this->operations_mutex->lock();
|
MutexLock lock(mut_this->operations_mutex);
|
||||||
mut_this->active = p_active;
|
mut_this->active = p_active;
|
||||||
mut_this->operations_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdNavigationServer::flush_queries() {
|
void GdNavigationServer::flush_queries() {
|
||||||
// In c++ we can't be sure that this is performed in the main thread
|
// In c++ we can't be sure that this is performed in the main thread
|
||||||
// even with mutable functions.
|
// even with mutable functions.
|
||||||
commands_mutex->lock();
|
MutexLock lock(commands_mutex);
|
||||||
operations_mutex->lock();
|
MutexLock lock2(operations_mutex);
|
||||||
for (size_t i(0); i < commands.size(); i++) {
|
for (size_t i(0); i < commands.size(); i++) {
|
||||||
commands[i]->exec(this);
|
commands[i]->exec(this);
|
||||||
memdelete(commands[i]);
|
memdelete(commands[i]);
|
||||||
}
|
}
|
||||||
commands.clear();
|
commands.clear();
|
||||||
operations_mutex->unlock();
|
|
||||||
commands_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdNavigationServer::process(real_t p_delta_time) {
|
void GdNavigationServer::process(real_t p_delta_time) {
|
||||||
|
@ -498,13 +489,12 @@ void GdNavigationServer::process(real_t p_delta_time) {
|
||||||
|
|
||||||
// In c++ we can't be sure that this is performed in the main thread
|
// In c++ we can't be sure that this is performed in the main thread
|
||||||
// even with mutable functions.
|
// even with mutable functions.
|
||||||
operations_mutex->lock();
|
MutexLock lock(operations_mutex);
|
||||||
for (int i(0); i < active_maps.size(); i++) {
|
for (int i(0); i < active_maps.size(); i++) {
|
||||||
active_maps[i]->sync();
|
active_maps[i]->sync();
|
||||||
active_maps[i]->step(p_delta_time);
|
active_maps[i]->step(p_delta_time);
|
||||||
active_maps[i]->dispatch_callbacks();
|
active_maps[i]->dispatch_callbacks();
|
||||||
}
|
}
|
||||||
operations_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef COMMAND_1
|
#undef COMMAND_1
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
|
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
|
||||||
|
|
||||||
class GdNavigationServer;
|
class GdNavigationServer;
|
||||||
class Mutex;
|
|
||||||
|
|
||||||
struct SetCommand {
|
struct SetCommand {
|
||||||
virtual ~SetCommand() {}
|
virtual ~SetCommand() {}
|
||||||
|
@ -69,9 +68,9 @@ struct SetCommand {
|
||||||
};
|
};
|
||||||
|
|
||||||
class GdNavigationServer : public NavigationServer {
|
class GdNavigationServer : public NavigationServer {
|
||||||
Mutex *commands_mutex;
|
Mutex commands_mutex;
|
||||||
/// Mutex used to make any operation threadsafe.
|
/// Mutex used to make any operation threadsafe.
|
||||||
Mutex *operations_mutex;
|
Mutex operations_mutex;
|
||||||
|
|
||||||
std::vector<SetCommand *> commands;
|
std::vector<SetCommand *> commands;
|
||||||
|
|
||||||
|
|
|
@ -104,28 +104,21 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
|
||||||
|
|
||||||
/* STEP 2, INITIALIZE AND CONSTRUCT */
|
/* STEP 2, INITIALIZE AND CONSTRUCT */
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
{
|
||||||
GDScriptLanguage::singleton->lock->lock();
|
MutexLock lock(GDScriptLanguage::singleton->lock);
|
||||||
#endif
|
|
||||||
|
|
||||||
instances.insert(instance->owner);
|
instances.insert(instance->owner);
|
||||||
|
}
|
||||||
#ifndef NO_THREADS
|
|
||||||
GDScriptLanguage::singleton->lock->unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
initializer->call(instance, p_args, p_argcount, r_error);
|
initializer->call(instance, p_args, p_argcount, r_error);
|
||||||
|
|
||||||
if (r_error.error != Callable::CallError::CALL_OK) {
|
if (r_error.error != Callable::CallError::CALL_OK) {
|
||||||
instance->script = Ref<GDScript>();
|
instance->script = Ref<GDScript>();
|
||||||
instance->owner->set_script_instance(NULL);
|
instance->owner->set_script_instance(NULL);
|
||||||
#ifndef NO_THREADS
|
{
|
||||||
GDScriptLanguage::singleton->lock->lock();
|
MutexLock lock(GDScriptLanguage::singleton->lock);
|
||||||
#endif
|
|
||||||
instances.erase(p_owner);
|
instances.erase(p_owner);
|
||||||
#ifndef NO_THREADS
|
}
|
||||||
GDScriptLanguage::singleton->lock->unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, NULL); //error constructing
|
ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, NULL); //error constructing
|
||||||
}
|
}
|
||||||
|
@ -346,16 +339,9 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
|
||||||
|
|
||||||
bool GDScript::instance_has(const Object *p_this) const {
|
bool GDScript::instance_has(const Object *p_this) const {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
MutexLock lock(GDScriptLanguage::singleton->lock);
|
||||||
GDScriptLanguage::singleton->lock->lock();
|
|
||||||
#endif
|
|
||||||
bool hasit = instances.has((Object *)p_this);
|
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
return instances.has((Object *)p_this);
|
||||||
GDScriptLanguage::singleton->lock->unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return hasit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDScript::has_source_code() const {
|
bool GDScript::has_source_code() const {
|
||||||
|
@ -544,14 +530,12 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
|
||||||
|
|
||||||
Error GDScript::reload(bool p_keep_state) {
|
Error GDScript::reload(bool p_keep_state) {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
bool has_instances;
|
||||||
GDScriptLanguage::singleton->lock->lock();
|
{
|
||||||
#endif
|
MutexLock lock(GDScriptLanguage::singleton->lock);
|
||||||
bool has_instances = instances.size();
|
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
has_instances = instances.size();
|
||||||
GDScriptLanguage::singleton->lock->unlock();
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
|
ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
|
||||||
|
|
||||||
|
@ -1007,13 +991,10 @@ GDScript::GDScript() :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
{
|
||||||
GDScriptLanguage::get_singleton()->lock->lock();
|
MutexLock lock(GDScriptLanguage::get_singleton()->lock);
|
||||||
}
|
|
||||||
GDScriptLanguage::get_singleton()->script_list.add(&script_list);
|
|
||||||
|
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
GDScriptLanguage::get_singleton()->script_list.add(&script_list);
|
||||||
GDScriptLanguage::get_singleton()->lock->unlock();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1057,13 +1038,10 @@ GDScript::~GDScript() {
|
||||||
_save_orphaned_subclasses();
|
_save_orphaned_subclasses();
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
{
|
||||||
GDScriptLanguage::get_singleton()->lock->lock();
|
MutexLock lock(GDScriptLanguage::get_singleton()->lock);
|
||||||
}
|
|
||||||
GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
|
|
||||||
|
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
|
||||||
GDScriptLanguage::get_singleton()->lock->unlock();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1472,14 +1450,9 @@ GDScriptInstance::GDScriptInstance() {
|
||||||
|
|
||||||
GDScriptInstance::~GDScriptInstance() {
|
GDScriptInstance::~GDScriptInstance() {
|
||||||
if (script.is_valid() && owner) {
|
if (script.is_valid() && owner) {
|
||||||
#ifndef NO_THREADS
|
MutexLock lock(GDScriptLanguage::singleton->lock);
|
||||||
GDScriptLanguage::singleton->lock->lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
script->instances.erase(owner);
|
script->instances.erase(owner);
|
||||||
#ifndef NO_THREADS
|
|
||||||
GDScriptLanguage::singleton->lock->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1580,9 +1553,7 @@ void GDScriptLanguage::finish() {
|
||||||
void GDScriptLanguage::profiling_start() {
|
void GDScriptLanguage::profiling_start() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (lock) {
|
MutexLock lock(this->lock);
|
||||||
lock->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
SelfList<GDScriptFunction> *elem = function_list.first();
|
SelfList<GDScriptFunction> *elem = function_list.first();
|
||||||
while (elem) {
|
while (elem) {
|
||||||
|
@ -1599,25 +1570,15 @@ void GDScriptLanguage::profiling_start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
profiling = true;
|
profiling = true;
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptLanguage::profiling_stop() {
|
void GDScriptLanguage::profiling_stop() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (lock) {
|
MutexLock lock(this->lock);
|
||||||
lock->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
profiling = false;
|
profiling = false;
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1625,9 +1586,8 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
|
||||||
|
|
||||||
int current = 0;
|
int current = 0;
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (lock) {
|
|
||||||
lock->lock();
|
MutexLock lock(this->lock);
|
||||||
}
|
|
||||||
|
|
||||||
SelfList<GDScriptFunction> *elem = function_list.first();
|
SelfList<GDScriptFunction> *elem = function_list.first();
|
||||||
while (elem) {
|
while (elem) {
|
||||||
|
@ -1640,11 +1600,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
current++;
|
current++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
@ -1655,9 +1610,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
|
||||||
int current = 0;
|
int current = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (lock) {
|
MutexLock lock(this->lock);
|
||||||
lock->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
SelfList<GDScriptFunction> *elem = function_list.first();
|
SelfList<GDScriptFunction> *elem = function_list.first();
|
||||||
while (elem) {
|
while (elem) {
|
||||||
|
@ -1672,11 +1625,6 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
|
||||||
}
|
}
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
@ -1707,11 +1655,9 @@ void GDScriptLanguage::reload_all_scripts() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
print_verbose("GDScript: Reloading all scripts");
|
print_verbose("GDScript: Reloading all scripts");
|
||||||
if (lock) {
|
|
||||||
lock->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Ref<GDScript> > scripts;
|
List<Ref<GDScript> > scripts;
|
||||||
|
{
|
||||||
|
MutexLock lock(this->lock);
|
||||||
|
|
||||||
SelfList<GDScript> *elem = script_list.first();
|
SelfList<GDScript> *elem = script_list.first();
|
||||||
while (elem) {
|
while (elem) {
|
||||||
|
@ -1721,9 +1667,6 @@ void GDScriptLanguage::reload_all_scripts() {
|
||||||
}
|
}
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//as scripts are going to be reloaded, must proceed without locking here
|
//as scripts are going to be reloaded, must proceed without locking here
|
||||||
|
@ -1743,11 +1686,9 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
lock->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Ref<GDScript> > scripts;
|
List<Ref<GDScript> > scripts;
|
||||||
|
{
|
||||||
|
MutexLock lock(this->lock);
|
||||||
|
|
||||||
SelfList<GDScript> *elem = script_list.first();
|
SelfList<GDScript> *elem = script_list.first();
|
||||||
while (elem) {
|
while (elem) {
|
||||||
|
@ -1757,9 +1698,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
|
||||||
}
|
}
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//when someone asks you why dynamically typed languages are easier to write....
|
//when someone asks you why dynamically typed languages are easier to write....
|
||||||
|
@ -1879,9 +1817,7 @@ void GDScriptLanguage::frame() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (profiling) {
|
if (profiling) {
|
||||||
if (lock) {
|
MutexLock lock(this->lock);
|
||||||
lock->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
SelfList<GDScriptFunction> *elem = function_list.first();
|
SelfList<GDScriptFunction> *elem = function_list.first();
|
||||||
while (elem) {
|
while (elem) {
|
||||||
|
@ -1893,10 +1829,6 @@ void GDScriptLanguage::frame() {
|
||||||
elem->self()->profile.frame_total_time = 0;
|
elem->self()->profile.frame_total_time = 0;
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
lock->unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2262,11 +2194,6 @@ GDScriptLanguage::GDScriptLanguage() {
|
||||||
_debug_parse_err_line = -1;
|
_debug_parse_err_line = -1;
|
||||||
_debug_parse_err_file = "";
|
_debug_parse_err_file = "";
|
||||||
|
|
||||||
#ifdef NO_THREADS
|
|
||||||
lock = NULL;
|
|
||||||
#else
|
|
||||||
lock = Mutex::create();
|
|
||||||
#endif
|
|
||||||
profiling = false;
|
profiling = false;
|
||||||
script_frame_time = 0;
|
script_frame_time = 0;
|
||||||
|
|
||||||
|
@ -2300,10 +2227,6 @@ GDScriptLanguage::GDScriptLanguage() {
|
||||||
|
|
||||||
GDScriptLanguage::~GDScriptLanguage() {
|
GDScriptLanguage::~GDScriptLanguage() {
|
||||||
|
|
||||||
if (lock) {
|
|
||||||
memdelete(lock);
|
|
||||||
lock = NULL;
|
|
||||||
}
|
|
||||||
if (_call_stack) {
|
if (_call_stack) {
|
||||||
memdelete_arr(_call_stack);
|
memdelete_arr(_call_stack);
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ class GDScriptLanguage : public ScriptLanguage {
|
||||||
|
|
||||||
friend class GDScriptInstance;
|
friend class GDScriptInstance;
|
||||||
|
|
||||||
Mutex *lock;
|
Mutex lock;
|
||||||
|
|
||||||
friend class GDScript;
|
friend class GDScript;
|
||||||
|
|
||||||
|
|
|
@ -1769,13 +1769,10 @@ GDScriptFunction::GDScriptFunction() :
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
_func_cname = NULL;
|
_func_cname = NULL;
|
||||||
|
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
{
|
||||||
GDScriptLanguage::get_singleton()->lock->lock();
|
MutexLock lock(GDScriptLanguage::get_singleton()->lock);
|
||||||
}
|
|
||||||
GDScriptLanguage::get_singleton()->function_list.add(&function_list);
|
|
||||||
|
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
GDScriptLanguage::get_singleton()->function_list.add(&function_list);
|
||||||
GDScriptLanguage::get_singleton()->lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.call_count = 0;
|
profile.call_count = 0;
|
||||||
|
@ -1793,14 +1790,10 @@ GDScriptFunction::GDScriptFunction() :
|
||||||
|
|
||||||
GDScriptFunction::~GDScriptFunction() {
|
GDScriptFunction::~GDScriptFunction() {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
|
||||||
GDScriptLanguage::get_singleton()->lock->lock();
|
|
||||||
}
|
|
||||||
GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
|
|
||||||
|
|
||||||
if (GDScriptLanguage::get_singleton()->lock) {
|
MutexLock lock(GDScriptLanguage::get_singleton()->lock);
|
||||||
GDScriptLanguage::get_singleton()->lock->unlock();
|
|
||||||
}
|
GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "core/io/json.h"
|
#include "core/io/json.h"
|
||||||
#include "core/os/file_access.h"
|
#include "core/os/file_access.h"
|
||||||
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
|
@ -58,7 +59,6 @@
|
||||||
#include "mono_gd/gd_mono_utils.h"
|
#include "mono_gd/gd_mono_utils.h"
|
||||||
#include "signal_awaiter_utils.h"
|
#include "signal_awaiter_utils.h"
|
||||||
#include "utils/macros.h"
|
#include "utils/macros.h"
|
||||||
#include "utils/mutex_utils.h"
|
|
||||||
#include "utils/string_utils.h"
|
#include "utils/string_utils.h"
|
||||||
#include "utils/thread_local.h"
|
#include "utils/thread_local.h"
|
||||||
|
|
||||||
|
@ -633,7 +633,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
|
||||||
|
|
||||||
void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
|
void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
|
MutexLock lock(unsafe_object_references_lock);
|
||||||
ObjectID id = p_obj->get_instance_id();
|
ObjectID id = p_obj->get_instance_id();
|
||||||
unsafe_object_references[id]++;
|
unsafe_object_references[id]++;
|
||||||
#endif
|
#endif
|
||||||
|
@ -641,7 +641,7 @@ void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
|
||||||
|
|
||||||
void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
|
void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
|
MutexLock lock(unsafe_object_references_lock);
|
||||||
ObjectID id = p_obj->get_instance_id();
|
ObjectID id = p_obj->get_instance_id();
|
||||||
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
|
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
|
||||||
ERR_FAIL_NULL(elem);
|
ERR_FAIL_NULL(elem);
|
||||||
|
@ -764,7 +764,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
||||||
List<Ref<CSharpScript> > scripts;
|
List<Ref<CSharpScript> > scripts;
|
||||||
|
|
||||||
{
|
{
|
||||||
SCOPED_MUTEX_LOCK(script_instances_mutex);
|
MutexLock lock(script_instances_mutex);
|
||||||
|
|
||||||
for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) {
|
for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) {
|
||||||
// Cast to CSharpScript to avoid being erased by accident
|
// Cast to CSharpScript to avoid being erased by accident
|
||||||
|
@ -1204,7 +1204,7 @@ void CSharpLanguage::set_language_index(int p_idx) {
|
||||||
void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
|
void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
|
||||||
|
|
||||||
if (!p_gchandle->is_released()) { // Do not lock unnecessarily
|
if (!p_gchandle->is_released()) { // Do not lock unnecessarily
|
||||||
SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
|
MutexLock lock(get_singleton()->script_gchandle_release_mutex);
|
||||||
p_gchandle->release();
|
p_gchandle->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1214,7 +1214,7 @@ void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<Mon
|
||||||
uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it
|
uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it
|
||||||
|
|
||||||
if (!p_gchandle->is_released()) { // Do not lock unnecessarily
|
if (!p_gchandle->is_released()) { // Do not lock unnecessarily
|
||||||
SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
|
MutexLock lock(get_singleton()->script_gchandle_release_mutex);
|
||||||
|
|
||||||
MonoObject *target = p_gchandle->get_target();
|
MonoObject *target = p_gchandle->get_target();
|
||||||
|
|
||||||
|
@ -1239,24 +1239,6 @@ CSharpLanguage::CSharpLanguage() {
|
||||||
|
|
||||||
gdmono = NULL;
|
gdmono = NULL;
|
||||||
|
|
||||||
#ifdef NO_THREADS
|
|
||||||
script_instances_mutex = NULL;
|
|
||||||
script_gchandle_release_mutex = NULL;
|
|
||||||
language_bind_mutex = NULL;
|
|
||||||
#else
|
|
||||||
script_instances_mutex = Mutex::create();
|
|
||||||
script_gchandle_release_mutex = Mutex::create();
|
|
||||||
language_bind_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
#ifdef NO_THREADS
|
|
||||||
unsafe_object_references_lock = NULL;
|
|
||||||
#else
|
|
||||||
unsafe_object_references_lock = Mutex::create();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lang_idx = -1;
|
lang_idx = -1;
|
||||||
|
|
||||||
scripts_metadata_invalidated = true;
|
scripts_metadata_invalidated = true;
|
||||||
|
@ -1269,29 +1251,6 @@ CSharpLanguage::CSharpLanguage() {
|
||||||
CSharpLanguage::~CSharpLanguage() {
|
CSharpLanguage::~CSharpLanguage() {
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
|
|
||||||
if (script_instances_mutex) {
|
|
||||||
memdelete(script_instances_mutex);
|
|
||||||
script_instances_mutex = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (language_bind_mutex) {
|
|
||||||
memdelete(language_bind_mutex);
|
|
||||||
language_bind_mutex = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (script_gchandle_release_mutex) {
|
|
||||||
memdelete(script_gchandle_release_mutex);
|
|
||||||
script_gchandle_release_mutex = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (unsafe_object_references_lock) {
|
|
||||||
memdelete(unsafe_object_references_lock);
|
|
||||||
unsafe_object_references_lock = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
singleton = NULL;
|
singleton = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1346,7 +1305,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
|
||||||
|
|
||||||
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
|
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
|
||||||
|
|
||||||
SCOPED_MUTEX_LOCK(language_bind_mutex);
|
MutexLock lock(language_bind_mutex);
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
|
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
|
||||||
if (match)
|
if (match)
|
||||||
|
@ -1381,7 +1340,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
|
||||||
GD_MONO_ASSERT_THREAD_ATTACHED;
|
GD_MONO_ASSERT_THREAD_ATTACHED;
|
||||||
|
|
||||||
{
|
{
|
||||||
SCOPED_MUTEX_LOCK(language_bind_mutex);
|
MutexLock lock(language_bind_mutex);
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
|
Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
|
||||||
|
|
||||||
|
@ -2187,7 +2146,7 @@ CSharpInstance::~CSharpInstance() {
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
||||||
|
|
||||||
if (!script_binding.inited) {
|
if (!script_binding.inited) {
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
||||||
|
|
||||||
if (!script_binding.inited) { // Other thread may have set it up
|
if (!script_binding.inited) { // Other thread may have set it up
|
||||||
// Already had a binding that needs to be setup
|
// Already had a binding that needs to be setup
|
||||||
|
@ -2203,7 +2162,7 @@ CSharpInstance::~CSharpInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script.is_valid() && owner) {
|
if (script.is_valid() && owner) {
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
|
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
// CSharpInstance must not be created unless it's going to be added to the list for sure
|
// CSharpInstance must not be created unless it's going to be added to the list for sure
|
||||||
|
@ -2979,7 +2938,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
|
||||||
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
|
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
|
||||||
|
|
||||||
{
|
{
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
|
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
|
||||||
instances.insert(instance->owner);
|
instances.insert(instance->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3067,7 +3026,7 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t
|
||||||
|
|
||||||
bool CSharpScript::instance_has(const Object *p_this) const {
|
bool CSharpScript::instance_has(const Object *p_this) const {
|
||||||
|
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
|
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
|
||||||
return instances.has((Object *)p_this);
|
return instances.has((Object *)p_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3140,7 +3099,7 @@ Error CSharpScript::reload(bool p_keep_state) {
|
||||||
|
|
||||||
bool has_instances;
|
bool has_instances;
|
||||||
{
|
{
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
|
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
|
||||||
has_instances = instances.size();
|
has_instances = instances.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3476,7 +3435,7 @@ CSharpScript::CSharpScript() :
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
{
|
{
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
|
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
|
||||||
CSharpLanguage::get_singleton()->script_list.add(&this->script_list);
|
CSharpLanguage::get_singleton()->script_list.add(&this->script_list);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3485,7 +3444,7 @@ CSharpScript::CSharpScript() :
|
||||||
CSharpScript::~CSharpScript() {
|
CSharpScript::~CSharpScript() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
|
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
|
||||||
CSharpLanguage::get_singleton()->script_list.remove(&this->script_list);
|
CSharpLanguage::get_singleton()->script_list.remove(&this->script_list);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,16 +325,16 @@ class CSharpLanguage : public ScriptLanguage {
|
||||||
GDMono *gdmono;
|
GDMono *gdmono;
|
||||||
SelfList<CSharpScript>::List script_list;
|
SelfList<CSharpScript>::List script_list;
|
||||||
|
|
||||||
Mutex *script_instances_mutex;
|
Mutex script_instances_mutex;
|
||||||
Mutex *script_gchandle_release_mutex;
|
Mutex script_gchandle_release_mutex;
|
||||||
Mutex *language_bind_mutex;
|
Mutex language_bind_mutex;
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding> script_bindings;
|
Map<Object *, CSharpScriptBinding> script_bindings;
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
// List of unsafe object references
|
// List of unsafe object references
|
||||||
Map<ObjectID, int> unsafe_object_references;
|
Map<ObjectID, int> unsafe_object_references;
|
||||||
Mutex *unsafe_object_references_lock;
|
Mutex unsafe_object_references_lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct StringNameCache {
|
struct StringNameCache {
|
||||||
|
@ -376,7 +376,7 @@ class CSharpLanguage : public ScriptLanguage {
|
||||||
public:
|
public:
|
||||||
StringNameCache string_names;
|
StringNameCache string_names;
|
||||||
|
|
||||||
Mutex *get_language_bind_mutex() { return language_bind_mutex; }
|
const Mutex &get_language_bind_mutex() { return language_bind_mutex; }
|
||||||
|
|
||||||
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
|
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
|
||||||
void set_language_index(int p_idx);
|
void set_language_index(int p_idx);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <mono/metadata/exception.h>
|
#include <mono/metadata/exception.h>
|
||||||
|
|
||||||
#include "core/os/dir_access.h"
|
#include "core/os/dir_access.h"
|
||||||
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
#include "core/reference.h"
|
#include "core/reference.h"
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
|
|
||||||
#include "../csharp_script.h"
|
#include "../csharp_script.h"
|
||||||
#include "../utils/macros.h"
|
#include "../utils/macros.h"
|
||||||
#include "../utils/mutex_utils.h"
|
|
||||||
#include "gd_mono.h"
|
#include "gd_mono.h"
|
||||||
#include "gd_mono_cache.h"
|
#include "gd_mono_cache.h"
|
||||||
#include "gd_mono_class.h"
|
#include "gd_mono_class.h"
|
||||||
|
@ -74,7 +74,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
|
||||||
|
|
||||||
if (!script_binding.inited) {
|
if (!script_binding.inited) {
|
||||||
SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
||||||
|
|
||||||
if (!script_binding.inited) { // Other thread may have set it up
|
if (!script_binding.inited) { // Other thread may have set it up
|
||||||
// Already had a binding that needs to be setup
|
// Already had a binding that needs to be setup
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* mutex_utils.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_UTILS_H
|
|
||||||
#define MUTEX_UTILS_H
|
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
|
||||||
#include "core/os/mutex.h"
|
|
||||||
|
|
||||||
#include "macros.h"
|
|
||||||
|
|
||||||
class ScopedMutexLock {
|
|
||||||
Mutex *mutex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ScopedMutexLock(Mutex *mutex) {
|
|
||||||
this->mutex = mutex;
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
CRASH_COND(!mutex);
|
|
||||||
#endif
|
|
||||||
this->mutex->lock();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedMutexLock() {
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
CRASH_COND(!mutex);
|
|
||||||
#endif
|
|
||||||
mutex->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SCOPED_MUTEX_LOCK(m_mutex) ScopedMutexLock GD_UNIQUE_NAME(__scoped_mutex_lock__)(m_mutex);
|
|
||||||
|
|
||||||
// TODO: Add version that receives a lambda instead, once C++11 is allowed
|
|
||||||
|
|
||||||
#endif // MUTEX_UTILS_H
|
|
|
@ -928,13 +928,11 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
|
||||||
VisualScriptInstance *instance = memnew(VisualScriptInstance);
|
VisualScriptInstance *instance = memnew(VisualScriptInstance);
|
||||||
instance->create(Ref<VisualScript>(this), p_this);
|
instance->create(Ref<VisualScript>(this), p_this);
|
||||||
|
|
||||||
if (VisualScriptLanguage::singleton->lock)
|
{
|
||||||
VisualScriptLanguage::singleton->lock->lock();
|
MutexLock lock(VisualScriptLanguage::singleton->lock);
|
||||||
|
|
||||||
instances[p_this] = instance;
|
instances[p_this] = instance;
|
||||||
|
}
|
||||||
if (VisualScriptLanguage::singleton->lock)
|
|
||||||
VisualScriptLanguage::singleton->lock->unlock();
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -2391,13 +2389,11 @@ VisualScriptInstance::VisualScriptInstance() {
|
||||||
|
|
||||||
VisualScriptInstance::~VisualScriptInstance() {
|
VisualScriptInstance::~VisualScriptInstance() {
|
||||||
|
|
||||||
if (VisualScriptLanguage::singleton->lock)
|
{
|
||||||
VisualScriptLanguage::singleton->lock->lock();
|
MutexLock lock(VisualScriptLanguage::singleton->lock);
|
||||||
|
|
||||||
script->instances.erase(owner);
|
script->instances.erase(owner);
|
||||||
|
}
|
||||||
if (VisualScriptLanguage::singleton->lock)
|
|
||||||
VisualScriptLanguage::singleton->lock->unlock();
|
|
||||||
|
|
||||||
for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) {
|
for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) {
|
||||||
memdelete(E->get());
|
memdelete(E->get());
|
||||||
|
@ -2836,9 +2832,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
|
||||||
_step = "_step";
|
_step = "_step";
|
||||||
_subcall = "_subcall";
|
_subcall = "_subcall";
|
||||||
singleton = this;
|
singleton = this;
|
||||||
#ifndef NO_THREADS
|
|
||||||
lock = Mutex::create();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_debug_parse_err_node = -1;
|
_debug_parse_err_node = -1;
|
||||||
_debug_parse_err_file = "";
|
_debug_parse_err_file = "";
|
||||||
|
@ -2859,9 +2852,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
|
||||||
|
|
||||||
VisualScriptLanguage::~VisualScriptLanguage() {
|
VisualScriptLanguage::~VisualScriptLanguage() {
|
||||||
|
|
||||||
if (lock)
|
|
||||||
memdelete(lock);
|
|
||||||
|
|
||||||
if (_call_stack) {
|
if (_call_stack) {
|
||||||
memdelete_arr(_call_stack);
|
memdelete_arr(_call_stack);
|
||||||
}
|
}
|
||||||
|
|
|
@ -530,7 +530,7 @@ public:
|
||||||
|
|
||||||
static VisualScriptLanguage *singleton;
|
static VisualScriptLanguage *singleton;
|
||||||
|
|
||||||
Mutex *lock;
|
Mutex lock;
|
||||||
|
|
||||||
bool debug_break(const String &p_error, bool p_allow_continue = true);
|
bool debug_break(const String &p_error, bool p_allow_continue = true);
|
||||||
bool debug_break_parse(const String &p_file, int p_node, const String &p_error);
|
bool debug_break_parse(const String &p_file, int p_node, const String &p_error);
|
||||||
|
|
|
@ -48,7 +48,7 @@ int AudioDriverAndroid::mix_rate = 44100;
|
||||||
bool AudioDriverAndroid::quit = false;
|
bool AudioDriverAndroid::quit = false;
|
||||||
jobject AudioDriverAndroid::audioBuffer = NULL;
|
jobject AudioDriverAndroid::audioBuffer = NULL;
|
||||||
void *AudioDriverAndroid::audioBufferPinned = NULL;
|
void *AudioDriverAndroid::audioBufferPinned = NULL;
|
||||||
Mutex *AudioDriverAndroid::mutex = NULL;
|
Mutex AudioDriverAndroid::mutex;
|
||||||
int32_t *AudioDriverAndroid::audioBuffer32 = NULL;
|
int32_t *AudioDriverAndroid::audioBuffer32 = NULL;
|
||||||
|
|
||||||
const char *AudioDriverAndroid::get_name() const {
|
const char *AudioDriverAndroid::get_name() const {
|
||||||
|
@ -58,7 +58,6 @@ const char *AudioDriverAndroid::get_name() const {
|
||||||
|
|
||||||
Error AudioDriverAndroid::init() {
|
Error AudioDriverAndroid::init() {
|
||||||
|
|
||||||
mutex = Mutex::create();
|
|
||||||
/*
|
/*
|
||||||
// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
|
// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
|
||||||
this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
||||||
|
@ -133,7 +132,7 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) {
|
||||||
int16_t *ptr = (int16_t *)audioBufferPinned;
|
int16_t *ptr = (int16_t *)audioBufferPinned;
|
||||||
int fc = audioBufferFrames;
|
int fc = audioBufferFrames;
|
||||||
|
|
||||||
if (!s_ad->active || mutex->try_lock() != OK) {
|
if (!s_ad->active || mutex.try_lock() != OK) {
|
||||||
|
|
||||||
for (int i = 0; i < fc; i++) {
|
for (int i = 0; i < fc; i++) {
|
||||||
ptr[i] = 0;
|
ptr[i] = 0;
|
||||||
|
@ -143,7 +142,7 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) {
|
||||||
|
|
||||||
s_ad->audio_server_process(fc / 2, audioBuffer32);
|
s_ad->audio_server_process(fc / 2, audioBuffer32);
|
||||||
|
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
|
|
||||||
for (int i = 0; i < fc; i++) {
|
for (int i = 0; i < fc; i++) {
|
||||||
|
|
||||||
|
@ -167,14 +166,12 @@ AudioDriver::SpeakerMode AudioDriverAndroid::get_speaker_mode() const {
|
||||||
|
|
||||||
void AudioDriverAndroid::lock() {
|
void AudioDriverAndroid::lock() {
|
||||||
|
|
||||||
if (mutex)
|
mutex.lock();
|
||||||
mutex->lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverAndroid::unlock() {
|
void AudioDriverAndroid::unlock() {
|
||||||
|
|
||||||
if (mutex)
|
mutex.unlock();
|
||||||
mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverAndroid::finish() {
|
void AudioDriverAndroid::finish() {
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
class AudioDriverAndroid : public AudioDriver {
|
class AudioDriverAndroid : public AudioDriver {
|
||||||
|
|
||||||
static Mutex *mutex;
|
static Mutex mutex;
|
||||||
static AudioDriverAndroid *s_ad;
|
static AudioDriverAndroid *s_ad;
|
||||||
static jobject io;
|
static jobject io;
|
||||||
static jmethodID _init_audio;
|
static jmethodID _init_audio;
|
||||||
|
|
|
@ -44,8 +44,8 @@ void AudioDriverOpenSL::_buffer_callback(
|
||||||
|
|
||||||
if (pause) {
|
if (pause) {
|
||||||
mix = false;
|
mix = false;
|
||||||
} else if (mutex) {
|
} else {
|
||||||
mix = mutex->try_lock() == OK;
|
mix = mutex.try_lock() == OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mix) {
|
if (mix) {
|
||||||
|
@ -58,8 +58,8 @@ void AudioDriverOpenSL::_buffer_callback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex && mix)
|
if (mix)
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
|
|
||||||
const int32_t *src_buff = mixdown_buffer;
|
const int32_t *src_buff = mixdown_buffer;
|
||||||
|
|
||||||
|
@ -107,7 +107,6 @@ Error AudioDriverOpenSL::init() {
|
||||||
|
|
||||||
void AudioDriverOpenSL::start() {
|
void AudioDriverOpenSL::start() {
|
||||||
|
|
||||||
mutex = Mutex::create();
|
|
||||||
active = false;
|
active = false;
|
||||||
|
|
||||||
SLresult res;
|
SLresult res;
|
||||||
|
@ -330,13 +329,13 @@ AudioDriver::SpeakerMode AudioDriverOpenSL::get_speaker_mode() const {
|
||||||
void AudioDriverOpenSL::lock() {
|
void AudioDriverOpenSL::lock() {
|
||||||
|
|
||||||
if (active && mutex)
|
if (active && mutex)
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverOpenSL::unlock() {
|
void AudioDriverOpenSL::unlock() {
|
||||||
|
|
||||||
if (active && mutex)
|
if (active && mutex)
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverOpenSL::finish() {
|
void AudioDriverOpenSL::finish() {
|
||||||
|
@ -359,7 +358,6 @@ void AudioDriverOpenSL::set_pause(bool p_pause) {
|
||||||
|
|
||||||
AudioDriverOpenSL::AudioDriverOpenSL() {
|
AudioDriverOpenSL::AudioDriverOpenSL() {
|
||||||
s_ad = this;
|
s_ad = this;
|
||||||
mutex = Mutex::create(); //NULL;
|
|
||||||
pause = false;
|
pause = false;
|
||||||
active = false;
|
active = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
class AudioDriverOpenSL : public AudioDriver {
|
class AudioDriverOpenSL : public AudioDriver {
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||||
|
|
||||||
Vector<Device> devices;
|
Vector<Device> devices;
|
||||||
volatile bool devices_changed;
|
volatile bool devices_changed;
|
||||||
Mutex *device_lock;
|
Mutex device_lock;
|
||||||
Thread *device_thread;
|
Thread *device_thread;
|
||||||
volatile bool quit_request;
|
volatile bool quit_request;
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||||
ldevices.push_back(d);
|
ldevices.push_back(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
ea->device_lock->lock();
|
MutexLock lock(ea->device_lock);
|
||||||
|
|
||||||
bool different = false;
|
bool different = false;
|
||||||
|
|
||||||
|
@ -381,8 +381,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||||
ea->devices = ndevices;
|
ea->devices = ndevices;
|
||||||
ea->devices_changed = true;
|
ea->devices_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ea->device_lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t sleep = 200;
|
uint64_t sleep = 200;
|
||||||
|
@ -1432,11 +1430,8 @@ public:
|
||||||
|
|
||||||
virtual int get_options_count() const {
|
virtual int get_options_count() const {
|
||||||
|
|
||||||
device_lock->lock();
|
MutexLock lock(device_lock);
|
||||||
int dc = devices.size();
|
return devices.size();
|
||||||
device_lock->unlock();
|
|
||||||
|
|
||||||
return dc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual String get_options_tooltip() const {
|
virtual String get_options_tooltip() const {
|
||||||
|
@ -1447,16 +1442,14 @@ public:
|
||||||
virtual String get_option_label(int p_index) const {
|
virtual String get_option_label(int p_index) const {
|
||||||
|
|
||||||
ERR_FAIL_INDEX_V(p_index, devices.size(), "");
|
ERR_FAIL_INDEX_V(p_index, devices.size(), "");
|
||||||
device_lock->lock();
|
MutexLock lock(device_lock);
|
||||||
String s = devices[p_index].name;
|
return devices[p_index].name;
|
||||||
device_lock->unlock();
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual String get_option_tooltip(int p_index) const {
|
virtual String get_option_tooltip(int p_index) const {
|
||||||
|
|
||||||
ERR_FAIL_INDEX_V(p_index, devices.size(), "");
|
ERR_FAIL_INDEX_V(p_index, devices.size(), "");
|
||||||
device_lock->lock();
|
MutexLock lock(device_lock);
|
||||||
String s = devices[p_index].description;
|
String s = devices[p_index].description;
|
||||||
if (devices.size() == 1) {
|
if (devices.size() == 1) {
|
||||||
// Tooltip will be:
|
// Tooltip will be:
|
||||||
|
@ -1464,7 +1457,6 @@ public:
|
||||||
// Description
|
// Description
|
||||||
s = devices[p_index].name + "\n\n" + s;
|
s = devices[p_index].name + "\n\n" + s;
|
||||||
}
|
}
|
||||||
device_lock->unlock();
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1479,7 +1471,7 @@ public:
|
||||||
return ERR_UNCONFIGURED;
|
return ERR_UNCONFIGURED;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_lock->lock();
|
MutexLock lock(device_lock);
|
||||||
|
|
||||||
EditorProgress ep("run", "Running on " + devices[p_device].name, 3);
|
EditorProgress ep("run", "Running on " + devices[p_device].name, 3);
|
||||||
|
|
||||||
|
@ -1487,7 +1479,6 @@ public:
|
||||||
|
|
||||||
// Export_temp APK.
|
// Export_temp APK.
|
||||||
if (ep.step("Exporting APK...", 0)) {
|
if (ep.step("Exporting APK...", 0)) {
|
||||||
device_lock->unlock();
|
|
||||||
return ERR_SKIP;
|
return ERR_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1502,7 +1493,6 @@ public:
|
||||||
#define CLEANUP_AND_RETURN(m_err) \
|
#define CLEANUP_AND_RETURN(m_err) \
|
||||||
{ \
|
{ \
|
||||||
DirAccess::remove_file_or_error(tmp_export_path); \
|
DirAccess::remove_file_or_error(tmp_export_path); \
|
||||||
device_lock->unlock(); \
|
|
||||||
return m_err; \
|
return m_err; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2570,7 +2560,6 @@ public:
|
||||||
run_icon.instance();
|
run_icon.instance();
|
||||||
run_icon->create_from_image(img);
|
run_icon->create_from_image(img);
|
||||||
|
|
||||||
device_lock = Mutex::create();
|
|
||||||
devices_changed = true;
|
devices_changed = true;
|
||||||
quit_request = false;
|
quit_request = false;
|
||||||
device_thread = Thread::create(_device_poll_thread, this);
|
device_thread = Thread::create(_device_poll_thread, this);
|
||||||
|
@ -2579,7 +2568,6 @@ public:
|
||||||
~EditorExportPlatformAndroid() {
|
~EditorExportPlatformAndroid() {
|
||||||
quit_request = true;
|
quit_request = true;
|
||||||
Thread::wait_to_finish(device_thread);
|
Thread::wait_to_finish(device_thread);
|
||||||
memdelete(device_lock);
|
|
||||||
memdelete(device_thread);
|
memdelete(device_thread);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -67,7 +67,6 @@ Error AudioDriverMediaKit::init() {
|
||||||
ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN);
|
ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex = Mutex::create();
|
|
||||||
player->Start();
|
player->Start();
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -108,14 +107,14 @@ void AudioDriverMediaKit::lock() {
|
||||||
if (!mutex)
|
if (!mutex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverMediaKit::unlock() {
|
void AudioDriverMediaKit::unlock() {
|
||||||
if (!mutex)
|
if (!mutex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverMediaKit::finish() {
|
void AudioDriverMediaKit::finish() {
|
||||||
|
@ -124,15 +123,9 @@ void AudioDriverMediaKit::finish() {
|
||||||
if (samples_in) {
|
if (samples_in) {
|
||||||
memdelete_arr(samples_in);
|
memdelete_arr(samples_in);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mutex) {
|
|
||||||
memdelete(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDriverMediaKit::AudioDriverMediaKit() {
|
AudioDriverMediaKit::AudioDriverMediaKit() {
|
||||||
mutex = NULL;
|
|
||||||
player = NULL;
|
player = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include <SoundPlayer.h>
|
#include <SoundPlayer.h>
|
||||||
|
|
||||||
class AudioDriverMediaKit : public AudioDriver {
|
class AudioDriverMediaKit : public AudioDriver {
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
BSoundPlayer *player;
|
BSoundPlayer *player;
|
||||||
static int32_t *samples_in;
|
static int32_t *samples_in;
|
||||||
|
|
|
@ -200,7 +200,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
|
||||||
private:
|
private:
|
||||||
Ref<EditorHTTPServer> server;
|
Ref<EditorHTTPServer> server;
|
||||||
bool server_quit;
|
bool server_quit;
|
||||||
Mutex *server_lock;
|
Mutex server_lock;
|
||||||
Thread *server_thread;
|
Thread *server_thread;
|
||||||
|
|
||||||
static void _server_thread_poll(void *data);
|
static void _server_thread_poll(void *data);
|
||||||
|
@ -531,9 +531,8 @@ bool EditorExportPlatformJavaScript::poll_export() {
|
||||||
menu_options = preset.is_valid();
|
menu_options = preset.is_valid();
|
||||||
if (server->is_listening()) {
|
if (server->is_listening()) {
|
||||||
if (menu_options == 0) {
|
if (menu_options == 0) {
|
||||||
server_lock->lock();
|
MutexLock lock(server_lock);
|
||||||
server->stop();
|
server->stop();
|
||||||
server_lock->unlock();
|
|
||||||
} else {
|
} else {
|
||||||
menu_options += 1;
|
menu_options += 1;
|
||||||
}
|
}
|
||||||
|
@ -553,9 +552,8 @@ int EditorExportPlatformJavaScript::get_options_count() const {
|
||||||
Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) {
|
Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) {
|
||||||
|
|
||||||
if (p_option == 1) {
|
if (p_option == 1) {
|
||||||
server_lock->lock();
|
MutexLock lock(server_lock);
|
||||||
server->stop();
|
server->stop();
|
||||||
server_lock->unlock();
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,10 +582,12 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
|
||||||
ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + bind_host + "'. Try using '127.0.0.1'.");
|
ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + bind_host + "'. Try using '127.0.0.1'.");
|
||||||
|
|
||||||
// Restart server.
|
// Restart server.
|
||||||
server_lock->lock();
|
{
|
||||||
|
MutexLock lock(server_lock);
|
||||||
|
|
||||||
server->stop();
|
server->stop();
|
||||||
err = server->listen(bind_port, bind_ip);
|
err = server->listen(bind_port, bind_ip);
|
||||||
server_lock->unlock();
|
}
|
||||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to start HTTP server.");
|
ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to start HTTP server.");
|
||||||
|
|
||||||
OS::get_singleton()->shell_open(String("http://" + bind_host + ":" + itos(bind_port) + "/tmp_js_export.html"));
|
OS::get_singleton()->shell_open(String("http://" + bind_host + ":" + itos(bind_port) + "/tmp_js_export.html"));
|
||||||
|
@ -605,9 +605,10 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) {
|
||||||
EditorExportPlatformJavaScript *ej = (EditorExportPlatformJavaScript *)data;
|
EditorExportPlatformJavaScript *ej = (EditorExportPlatformJavaScript *)data;
|
||||||
while (!ej->server_quit) {
|
while (!ej->server_quit) {
|
||||||
OS::get_singleton()->delay_usec(1000);
|
OS::get_singleton()->delay_usec(1000);
|
||||||
ej->server_lock->lock();
|
{
|
||||||
|
MutexLock lock(ej->server_lock);
|
||||||
ej->server->poll();
|
ej->server->poll();
|
||||||
ej->server_lock->unlock();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +616,6 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
|
||||||
|
|
||||||
server.instance();
|
server.instance();
|
||||||
server_quit = false;
|
server_quit = false;
|
||||||
server_lock = Mutex::create();
|
|
||||||
server_thread = Thread::create(_server_thread_poll, this);
|
server_thread = Thread::create(_server_thread_poll, this);
|
||||||
|
|
||||||
Ref<Image> img = memnew(Image(_javascript_logo));
|
Ref<Image> img = memnew(Image(_javascript_logo));
|
||||||
|
@ -639,7 +639,6 @@ EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
|
||||||
server->stop();
|
server->stop();
|
||||||
server_quit = true;
|
server_quit = true;
|
||||||
Thread::wait_to_finish(server_thread);
|
Thread::wait_to_finish(server_thread);
|
||||||
memdelete(server_lock);
|
|
||||||
memdelete(server_thread);
|
memdelete(server_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,6 @@ void OS_UWP::initialize_core() {
|
||||||
|
|
||||||
ThreadUWP::make_default();
|
ThreadUWP::make_default();
|
||||||
SemaphoreWindows::make_default();
|
SemaphoreWindows::make_default();
|
||||||
MutexWindows::make_default();
|
|
||||||
RWLockWindows::make_default();
|
RWLockWindows::make_default();
|
||||||
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
||||||
|
|
|
@ -47,7 +47,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/rw_lock_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"
|
||||||
|
@ -230,7 +229,6 @@ void OS_Windows::initialize_core() {
|
||||||
|
|
||||||
ThreadWindows::make_default();
|
ThreadWindows::make_default();
|
||||||
SemaphoreWindows::make_default();
|
SemaphoreWindows::make_default();
|
||||||
MutexWindows::make_default();
|
|
||||||
RWLockWindows::make_default();
|
RWLockWindows::make_default();
|
||||||
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
||||||
|
|
|
@ -83,7 +83,6 @@ void JoypadLinux::Joypad::reset() {
|
||||||
JoypadLinux::JoypadLinux(InputDefault *in) {
|
JoypadLinux::JoypadLinux(InputDefault *in) {
|
||||||
exit_udev = false;
|
exit_udev = false;
|
||||||
input = in;
|
input = in;
|
||||||
joy_mutex = Mutex::create();
|
|
||||||
joy_thread = Thread::create(joy_thread_func, this);
|
joy_thread = Thread::create(joy_thread_func, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +90,6 @@ JoypadLinux::~JoypadLinux() {
|
||||||
exit_udev = true;
|
exit_udev = true;
|
||||||
Thread::wait_to_finish(joy_thread);
|
Thread::wait_to_finish(joy_thread);
|
||||||
memdelete(joy_thread);
|
memdelete(joy_thread);
|
||||||
memdelete(joy_mutex);
|
|
||||||
close_joypad();
|
close_joypad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,9 +135,8 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
|
||||||
|
|
||||||
String devnode_str = devnode;
|
String devnode_str = devnode;
|
||||||
if (devnode_str.find(ignore_str) == -1) {
|
if (devnode_str.find(ignore_str) == -1) {
|
||||||
joy_mutex->lock();
|
MutexLock lock(joy_mutex);
|
||||||
open_joypad(devnode);
|
open_joypad(devnode);
|
||||||
joy_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
|
@ -176,7 +173,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
|
||||||
|
|
||||||
if (dev && udev_device_get_devnode(dev) != 0) {
|
if (dev && udev_device_get_devnode(dev) != 0) {
|
||||||
|
|
||||||
joy_mutex->lock();
|
MutexLock lock(joy_mutex);
|
||||||
String action = udev_device_get_action(dev);
|
String action = udev_device_get_action(dev);
|
||||||
const char *devnode = udev_device_get_devnode(dev);
|
const char *devnode = udev_device_get_devnode(dev);
|
||||||
if (devnode) {
|
if (devnode) {
|
||||||
|
@ -192,7 +189,6 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
joy_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usleep(50000);
|
usleep(50000);
|
||||||
|
@ -204,7 +200,9 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
|
||||||
void JoypadLinux::monitor_joypads() {
|
void JoypadLinux::monitor_joypads() {
|
||||||
|
|
||||||
while (!exit_udev) {
|
while (!exit_udev) {
|
||||||
joy_mutex->lock();
|
{
|
||||||
|
MutexLock lock(joy_mutex);
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
char fname[64];
|
char fname[64];
|
||||||
sprintf(fname, "/dev/input/event%d", i);
|
sprintf(fname, "/dev/input/event%d", i);
|
||||||
|
@ -212,7 +210,7 @@ void JoypadLinux::monitor_joypads() {
|
||||||
open_joypad(fname);
|
open_joypad(fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
joy_mutex->unlock();
|
}
|
||||||
usleep(1000000); // 1s
|
usleep(1000000); // 1s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,7 +455,7 @@ InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int
|
||||||
|
|
||||||
void JoypadLinux::process_joypads() {
|
void JoypadLinux::process_joypads() {
|
||||||
|
|
||||||
if (joy_mutex->try_lock() != OK) {
|
if (joy_mutex.try_lock() != OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < JOYPADS_MAX; i++) {
|
for (int i = 0; i < JOYPADS_MAX; i++) {
|
||||||
|
@ -548,6 +546,6 @@ void JoypadLinux::process_joypads() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
joy_mutex->unlock();
|
joy_mutex.unlock();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -72,7 +72,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool exit_udev;
|
bool exit_udev;
|
||||||
Mutex *joy_mutex;
|
Mutex joy_mutex;
|
||||||
Thread *joy_thread;
|
Thread *joy_thread;
|
||||||
InputDefault *input;
|
InputDefault *input;
|
||||||
Joypad joypads[JOYPADS_MAX];
|
Joypad joypads[JOYPADS_MAX];
|
||||||
|
|
|
@ -41,17 +41,13 @@
|
||||||
#include "servers/visual/visual_server_raster.h"
|
#include "servers/visual/visual_server_raster.h"
|
||||||
#include "servers/visual_server.h"
|
#include "servers/visual_server.h"
|
||||||
|
|
||||||
Mutex *CanvasItemMaterial::material_mutex = NULL;
|
Mutex CanvasItemMaterial::material_mutex;
|
||||||
SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL;
|
SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL;
|
||||||
Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map;
|
Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map;
|
||||||
CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL;
|
CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL;
|
||||||
|
|
||||||
void CanvasItemMaterial::init_shaders() {
|
void CanvasItemMaterial::init_shaders() {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
material_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dirty_materials = memnew(SelfList<CanvasItemMaterial>::List);
|
dirty_materials = memnew(SelfList<CanvasItemMaterial>::List);
|
||||||
|
|
||||||
shader_names = memnew(ShaderNames);
|
shader_names = memnew(ShaderNames);
|
||||||
|
@ -66,10 +62,6 @@ void CanvasItemMaterial::finish_shaders() {
|
||||||
memdelete(dirty_materials);
|
memdelete(dirty_materials);
|
||||||
memdelete(shader_names);
|
memdelete(shader_names);
|
||||||
dirty_materials = NULL;
|
dirty_materials = NULL;
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(material_mutex);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItemMaterial::_update_shader() {
|
void CanvasItemMaterial::_update_shader() {
|
||||||
|
@ -156,44 +148,28 @@ void CanvasItemMaterial::_update_shader() {
|
||||||
|
|
||||||
void CanvasItemMaterial::flush_changes() {
|
void CanvasItemMaterial::flush_changes() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
while (dirty_materials->first()) {
|
while (dirty_materials->first()) {
|
||||||
|
|
||||||
dirty_materials->first()->self()->_update_shader();
|
dirty_materials->first()->self()->_update_shader();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItemMaterial::_queue_shader_change() {
|
void CanvasItemMaterial::_queue_shader_change() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
if (!element.in_list()) {
|
if (!element.in_list()) {
|
||||||
dirty_materials->add(&element);
|
dirty_materials->add(&element);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanvasItemMaterial::_is_shader_dirty() const {
|
bool CanvasItemMaterial::_is_shader_dirty() const {
|
||||||
|
|
||||||
bool dirty = false;
|
MutexLock lock(material_mutex);
|
||||||
|
|
||||||
if (material_mutex)
|
return element.in_list();
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
dirty = element.in_list();
|
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
|
|
||||||
return dirty;
|
|
||||||
}
|
}
|
||||||
void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) {
|
void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) {
|
||||||
|
|
||||||
|
@ -332,8 +308,7 @@ CanvasItemMaterial::CanvasItemMaterial() :
|
||||||
|
|
||||||
CanvasItemMaterial::~CanvasItemMaterial() {
|
CanvasItemMaterial::~CanvasItemMaterial() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
if (shader_map.has(current_key)) {
|
if (shader_map.has(current_key)) {
|
||||||
shader_map[current_key].users--;
|
shader_map[current_key].users--;
|
||||||
|
@ -345,9 +320,6 @@ CanvasItemMaterial::~CanvasItemMaterial() {
|
||||||
|
|
||||||
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -108,7 +108,7 @@ private:
|
||||||
return mk;
|
return mk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mutex *material_mutex;
|
static Mutex material_mutex;
|
||||||
static SelfList<CanvasItemMaterial>::List *dirty_materials;
|
static SelfList<CanvasItemMaterial>::List *dirty_materials;
|
||||||
SelfList<CanvasItemMaterial> element;
|
SelfList<CanvasItemMaterial> element;
|
||||||
|
|
||||||
|
|
|
@ -970,11 +970,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles2D::_update_particle_data_buffer() {
|
void CPUParticles2D::_update_particle_data_buffer() {
|
||||||
#ifndef NO_THREADS
|
MutexLock lock(update_mutex);
|
||||||
update_mutex->lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
int pc = particles.size();
|
int pc = particles.size();
|
||||||
|
|
||||||
|
@ -1040,18 +1036,14 @@ void CPUParticles2D::_update_particle_data_buffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPUParticles2D::_set_redraw(bool p_redraw) {
|
void CPUParticles2D::_set_redraw(bool p_redraw) {
|
||||||
if (redraw == p_redraw)
|
if (redraw == p_redraw)
|
||||||
return;
|
return;
|
||||||
redraw = p_redraw;
|
redraw = p_redraw;
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex->lock();
|
{
|
||||||
#endif
|
MutexLock lock(update_mutex);
|
||||||
|
|
||||||
if (redraw) {
|
if (redraw) {
|
||||||
VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread");
|
VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread");
|
||||||
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
|
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
|
||||||
|
@ -1065,23 +1057,16 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
|
||||||
|
|
||||||
VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
|
VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
|
||||||
}
|
}
|
||||||
#ifndef NO_THREADS
|
}
|
||||||
update_mutex->unlock();
|
|
||||||
#endif
|
|
||||||
update(); // redraw to update render list
|
update(); // redraw to update render list
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles2D::_update_render_thread() {
|
void CPUParticles2D::_update_render_thread() {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
MutexLock lock(update_mutex);
|
||||||
update_mutex->lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
|
VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles2D::_notification(int p_what) {
|
void CPUParticles2D::_notification(int p_what) {
|
||||||
|
@ -1494,18 +1479,10 @@ CPUParticles2D::CPUParticles2D() {
|
||||||
|
|
||||||
set_color(Color(1, 1, 1, 1));
|
set_color(Color(1, 1, 1, 1));
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_update_mesh_texture();
|
_update_mesh_texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUParticles2D::~CPUParticles2D() {
|
CPUParticles2D::~CPUParticles2D() {
|
||||||
VS::get_singleton()->free(multimesh);
|
VS::get_singleton()->free(multimesh);
|
||||||
VS::get_singleton()->free(mesh);
|
VS::get_singleton()->free(mesh);
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(update_mutex);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ private:
|
||||||
void _particles_process(float p_delta);
|
void _particles_process(float p_delta);
|
||||||
void _update_particle_data_buffer();
|
void _update_particle_data_buffer();
|
||||||
|
|
||||||
Mutex *update_mutex;
|
Mutex update_mutex;
|
||||||
|
|
||||||
void _update_render_thread();
|
void _update_render_thread();
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,10 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double
|
||||||
|
|
||||||
void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) {
|
void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) {
|
||||||
|
|
||||||
navmesh_generation->lock();
|
{
|
||||||
|
MutexLock lock(navmesh_generation);
|
||||||
navmesh.unref();
|
navmesh.unref();
|
||||||
navmesh_generation->unlock();
|
}
|
||||||
vertices = p_vertices;
|
vertices = p_vertices;
|
||||||
rect_cache_dirty = true;
|
rect_cache_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -96,9 +97,10 @@ Vector<Vector2> NavigationPolygon::get_vertices() const {
|
||||||
|
|
||||||
void NavigationPolygon::_set_polygons(const Array &p_array) {
|
void NavigationPolygon::_set_polygons(const Array &p_array) {
|
||||||
|
|
||||||
navmesh_generation->lock();
|
{
|
||||||
|
MutexLock lock(navmesh_generation);
|
||||||
navmesh.unref();
|
navmesh.unref();
|
||||||
navmesh_generation->unlock();
|
}
|
||||||
polygons.resize(p_array.size());
|
polygons.resize(p_array.size());
|
||||||
for (int i = 0; i < p_array.size(); i++) {
|
for (int i = 0; i < p_array.size(); i++) {
|
||||||
polygons.write[i].indices = p_array[i];
|
polygons.write[i].indices = p_array[i];
|
||||||
|
@ -141,9 +143,10 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
|
||||||
Polygon polygon;
|
Polygon polygon;
|
||||||
polygon.indices = p_polygon;
|
polygon.indices = p_polygon;
|
||||||
polygons.push_back(polygon);
|
polygons.push_back(polygon);
|
||||||
navmesh_generation->lock();
|
{
|
||||||
|
MutexLock lock(navmesh_generation);
|
||||||
navmesh.unref();
|
navmesh.unref();
|
||||||
navmesh_generation->unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) {
|
void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) {
|
||||||
|
@ -164,13 +167,15 @@ Vector<int> NavigationPolygon::get_polygon(int p_idx) {
|
||||||
void NavigationPolygon::clear_polygons() {
|
void NavigationPolygon::clear_polygons() {
|
||||||
|
|
||||||
polygons.clear();
|
polygons.clear();
|
||||||
navmesh_generation->lock();
|
{
|
||||||
|
MutexLock lock(navmesh_generation);
|
||||||
navmesh.unref();
|
navmesh.unref();
|
||||||
navmesh_generation->unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<NavigationMesh> NavigationPolygon::get_mesh() {
|
Ref<NavigationMesh> NavigationPolygon::get_mesh() {
|
||||||
navmesh_generation->lock();
|
MutexLock lock(navmesh_generation);
|
||||||
|
|
||||||
if (navmesh.is_null()) {
|
if (navmesh.is_null()) {
|
||||||
navmesh.instance();
|
navmesh.instance();
|
||||||
Vector<Vector3> verts;
|
Vector<Vector3> verts;
|
||||||
|
@ -190,7 +195,7 @@ Ref<NavigationMesh> NavigationPolygon::get_mesh() {
|
||||||
navmesh->add_polygon(get_polygon(i));
|
navmesh->add_polygon(get_polygon(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
navmesh_generation->unlock();
|
|
||||||
return navmesh;
|
return navmesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,9 +235,10 @@ void NavigationPolygon::clear_outlines() {
|
||||||
}
|
}
|
||||||
void NavigationPolygon::make_polygons_from_outlines() {
|
void NavigationPolygon::make_polygons_from_outlines() {
|
||||||
|
|
||||||
navmesh_generation->lock();
|
{
|
||||||
|
MutexLock lock(navmesh_generation);
|
||||||
navmesh.unref();
|
navmesh.unref();
|
||||||
navmesh_generation->unlock();
|
}
|
||||||
List<TriangulatorPoly> in_poly, out_poly;
|
List<TriangulatorPoly> in_poly, out_poly;
|
||||||
|
|
||||||
Vector2 outside_point(-1e10, -1e10);
|
Vector2 outside_point(-1e10, -1e10);
|
||||||
|
@ -362,12 +368,10 @@ void NavigationPolygon::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationPolygon::NavigationPolygon() :
|
NavigationPolygon::NavigationPolygon() :
|
||||||
rect_cache_dirty(true),
|
rect_cache_dirty(true) {
|
||||||
navmesh_generation(Mutex::create()) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationPolygon::~NavigationPolygon() {
|
NavigationPolygon::~NavigationPolygon() {
|
||||||
memdelete(navmesh_generation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationPolygonInstance::set_enabled(bool p_enabled) {
|
void NavigationPolygonInstance::set_enabled(bool p_enabled) {
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
#include "scene/2d/node_2d.h"
|
#include "scene/2d/node_2d.h"
|
||||||
#include "scene/resources/navigation_mesh.h"
|
#include "scene/resources/navigation_mesh.h"
|
||||||
|
|
||||||
class Mutex;
|
|
||||||
|
|
||||||
class NavigationPolygon : public Resource {
|
class NavigationPolygon : public Resource {
|
||||||
|
|
||||||
GDCLASS(NavigationPolygon, Resource);
|
GDCLASS(NavigationPolygon, Resource);
|
||||||
|
@ -50,7 +48,7 @@ class NavigationPolygon : public Resource {
|
||||||
mutable Rect2 item_rect;
|
mutable Rect2 item_rect;
|
||||||
mutable bool rect_cache_dirty;
|
mutable bool rect_cache_dirty;
|
||||||
|
|
||||||
Mutex *navmesh_generation;
|
Mutex navmesh_generation;
|
||||||
// Navigation mesh
|
// Navigation mesh
|
||||||
Ref<NavigationMesh> navmesh;
|
Ref<NavigationMesh> navmesh;
|
||||||
|
|
||||||
|
|
|
@ -1017,11 +1017,7 @@ void CPUParticles::_particles_process(float p_delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles::_update_particle_data_buffer() {
|
void CPUParticles::_update_particle_data_buffer() {
|
||||||
#ifndef NO_THREADS
|
MutexLock lock(update_mutex);
|
||||||
update_mutex->lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
int pc = particles.size();
|
int pc = particles.size();
|
||||||
|
|
||||||
|
@ -1110,18 +1106,14 @@ void CPUParticles::_update_particle_data_buffer() {
|
||||||
can_update = true;
|
can_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPUParticles::_set_redraw(bool p_redraw) {
|
void CPUParticles::_set_redraw(bool p_redraw) {
|
||||||
if (redraw == p_redraw)
|
if (redraw == p_redraw)
|
||||||
return;
|
return;
|
||||||
redraw = p_redraw;
|
redraw = p_redraw;
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex->lock();
|
{
|
||||||
#endif
|
MutexLock lock(update_mutex);
|
||||||
|
|
||||||
if (redraw) {
|
if (redraw) {
|
||||||
VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread");
|
VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread");
|
||||||
VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
|
VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
|
||||||
|
@ -1133,24 +1125,17 @@ void CPUParticles::_set_redraw(bool p_redraw) {
|
||||||
VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
|
VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
|
||||||
VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
|
VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
|
||||||
}
|
}
|
||||||
#ifndef NO_THREADS
|
}
|
||||||
update_mutex->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles::_update_render_thread() {
|
void CPUParticles::_update_render_thread() {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
MutexLock lock(update_mutex);
|
||||||
update_mutex->lock();
|
|
||||||
#endif
|
|
||||||
if (can_update) {
|
if (can_update) {
|
||||||
VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
|
VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
|
||||||
can_update = false; //wait for next time
|
can_update = false; //wait for next time
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex->unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles::_notification(int p_what) {
|
void CPUParticles::_notification(int p_what) {
|
||||||
|
@ -1556,16 +1541,8 @@ CPUParticles::CPUParticles() {
|
||||||
can_update = false;
|
can_update = false;
|
||||||
|
|
||||||
set_color(Color(1, 1, 1, 1));
|
set_color(Color(1, 1, 1, 1));
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
update_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUParticles::~CPUParticles() {
|
CPUParticles::~CPUParticles() {
|
||||||
VS::get_singleton()->free(multimesh);
|
VS::get_singleton()->free(multimesh);
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(update_mutex);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ private:
|
||||||
void _particles_process(float p_delta);
|
void _particles_process(float p_delta);
|
||||||
void _update_particle_data_buffer();
|
void _update_particle_data_buffer();
|
||||||
|
|
||||||
Mutex *update_mutex;
|
Mutex update_mutex;
|
||||||
|
|
||||||
void _update_render_thread();
|
void _update_render_thread();
|
||||||
|
|
||||||
|
|
|
@ -990,7 +990,7 @@ void DynamicFont::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(SPACING_SPACE);
|
BIND_ENUM_CONSTANT(SPACING_SPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex *DynamicFont::dynamic_font_mutex = NULL;
|
Mutex DynamicFont::dynamic_font_mutex;
|
||||||
|
|
||||||
SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL;
|
SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL;
|
||||||
|
|
||||||
|
@ -1004,29 +1004,21 @@ DynamicFont::DynamicFont() :
|
||||||
spacing_char = 0;
|
spacing_char = 0;
|
||||||
spacing_space = 0;
|
spacing_space = 0;
|
||||||
outline_color = Color(1, 1, 1);
|
outline_color = Color(1, 1, 1);
|
||||||
if (dynamic_font_mutex) {
|
|
||||||
dynamic_font_mutex->lock();
|
MutexLock lock(dynamic_font_mutex);
|
||||||
dynamic_fonts->add(&font_list);
|
dynamic_fonts->add(&font_list);
|
||||||
dynamic_font_mutex->unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicFont::~DynamicFont() {
|
DynamicFont::~DynamicFont() {
|
||||||
if (dynamic_font_mutex) {
|
MutexLock lock(dynamic_font_mutex);
|
||||||
dynamic_font_mutex->lock();
|
|
||||||
dynamic_fonts->remove(&font_list);
|
dynamic_fonts->remove(&font_list);
|
||||||
dynamic_font_mutex->unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicFont::initialize_dynamic_fonts() {
|
void DynamicFont::initialize_dynamic_fonts() {
|
||||||
dynamic_fonts = memnew(SelfList<DynamicFont>::List());
|
dynamic_fonts = memnew(SelfList<DynamicFont>::List());
|
||||||
dynamic_font_mutex = Mutex::create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicFont::finish_dynamic_fonts() {
|
void DynamicFont::finish_dynamic_fonts() {
|
||||||
memdelete(dynamic_font_mutex);
|
|
||||||
dynamic_font_mutex = NULL;
|
|
||||||
memdelete(dynamic_fonts);
|
memdelete(dynamic_fonts);
|
||||||
dynamic_fonts = NULL;
|
dynamic_fonts = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1034,9 +1026,8 @@ void DynamicFont::finish_dynamic_fonts() {
|
||||||
void DynamicFont::update_oversampling() {
|
void DynamicFont::update_oversampling() {
|
||||||
|
|
||||||
Vector<Ref<DynamicFont> > changed;
|
Vector<Ref<DynamicFont> > changed;
|
||||||
|
{
|
||||||
if (dynamic_font_mutex)
|
MutexLock lock(dynamic_font_mutex);
|
||||||
dynamic_font_mutex->lock();
|
|
||||||
|
|
||||||
SelfList<DynamicFont> *E = dynamic_fonts->first();
|
SelfList<DynamicFont> *E = dynamic_fonts->first();
|
||||||
while (E) {
|
while (E) {
|
||||||
|
@ -1063,9 +1054,7 @@ void DynamicFont::update_oversampling() {
|
||||||
|
|
||||||
E = E->next();
|
E = E->next();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (dynamic_font_mutex)
|
|
||||||
dynamic_font_mutex->unlock();
|
|
||||||
|
|
||||||
for (int i = 0; i < changed.size(); i++) {
|
for (int i = 0; i < changed.size(); i++) {
|
||||||
changed.write[i]->emit_changed();
|
changed.write[i]->emit_changed();
|
||||||
|
|
|
@ -285,7 +285,7 @@ public:
|
||||||
|
|
||||||
SelfList<DynamicFont> font_list;
|
SelfList<DynamicFont> font_list;
|
||||||
|
|
||||||
static Mutex *dynamic_font_mutex;
|
static Mutex dynamic_font_mutex;
|
||||||
static SelfList<DynamicFont>::List *dynamic_fonts;
|
static SelfList<DynamicFont>::List *dynamic_fonts;
|
||||||
|
|
||||||
static void initialize_dynamic_fonts();
|
static void initialize_dynamic_fonts();
|
||||||
|
|
|
@ -290,17 +290,13 @@ ShaderMaterial::~ShaderMaterial() {
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
Mutex *BaseMaterial3D::material_mutex = NULL;
|
Mutex BaseMaterial3D::material_mutex;
|
||||||
SelfList<BaseMaterial3D>::List *BaseMaterial3D::dirty_materials = NULL;
|
SelfList<BaseMaterial3D>::List *BaseMaterial3D::dirty_materials = NULL;
|
||||||
Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::shader_map;
|
Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::shader_map;
|
||||||
BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = NULL;
|
BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = NULL;
|
||||||
|
|
||||||
void BaseMaterial3D::init_shaders() {
|
void BaseMaterial3D::init_shaders() {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
material_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dirty_materials = memnew(SelfList<BaseMaterial3D>::List);
|
dirty_materials = memnew(SelfList<BaseMaterial3D>::List);
|
||||||
|
|
||||||
shader_names = memnew(ShaderNames);
|
shader_names = memnew(ShaderNames);
|
||||||
|
@ -379,10 +375,6 @@ void BaseMaterial3D::finish_shaders() {
|
||||||
materials_for_2d[i].unref();
|
materials_for_2d[i].unref();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(material_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memdelete(dirty_materials);
|
memdelete(dirty_materials);
|
||||||
dirty_materials = NULL;
|
dirty_materials = NULL;
|
||||||
|
|
||||||
|
@ -1133,44 +1125,28 @@ void BaseMaterial3D::_update_shader() {
|
||||||
|
|
||||||
void BaseMaterial3D::flush_changes() {
|
void BaseMaterial3D::flush_changes() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
while (dirty_materials->first()) {
|
while (dirty_materials->first()) {
|
||||||
|
|
||||||
dirty_materials->first()->self()->_update_shader();
|
dirty_materials->first()->self()->_update_shader();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseMaterial3D::_queue_shader_change() {
|
void BaseMaterial3D::_queue_shader_change() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
if (!element.in_list()) {
|
if (!element.in_list()) {
|
||||||
dirty_materials->add(&element);
|
dirty_materials->add(&element);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseMaterial3D::_is_shader_dirty() const {
|
bool BaseMaterial3D::_is_shader_dirty() const {
|
||||||
|
|
||||||
bool dirty = false;
|
MutexLock lock(material_mutex);
|
||||||
|
|
||||||
if (material_mutex)
|
return element.in_list();
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
dirty = element.in_list();
|
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
|
|
||||||
return dirty;
|
|
||||||
}
|
}
|
||||||
void BaseMaterial3D::set_albedo(const Color &p_albedo) {
|
void BaseMaterial3D::set_albedo(const Color &p_albedo) {
|
||||||
|
|
||||||
|
@ -2580,8 +2556,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
|
||||||
|
|
||||||
BaseMaterial3D::~BaseMaterial3D() {
|
BaseMaterial3D::~BaseMaterial3D() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
if (shader_map.has(current_key)) {
|
if (shader_map.has(current_key)) {
|
||||||
shader_map[current_key].users--;
|
shader_map[current_key].users--;
|
||||||
|
@ -2593,9 +2568,6 @@ BaseMaterial3D::~BaseMaterial3D() {
|
||||||
|
|
||||||
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
|
|
|
@ -388,7 +388,7 @@ private:
|
||||||
StringName texture_names[TEXTURE_MAX];
|
StringName texture_names[TEXTURE_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
static Mutex *material_mutex;
|
static Mutex material_mutex;
|
||||||
static SelfList<BaseMaterial3D>::List *dirty_materials;
|
static SelfList<BaseMaterial3D>::List *dirty_materials;
|
||||||
static ShaderNames *shader_names;
|
static ShaderNames *shader_names;
|
||||||
|
|
||||||
|
|
|
@ -30,17 +30,13 @@
|
||||||
|
|
||||||
#include "particles_material.h"
|
#include "particles_material.h"
|
||||||
|
|
||||||
Mutex *ParticlesMaterial::material_mutex = NULL;
|
Mutex ParticlesMaterial::material_mutex;
|
||||||
SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL;
|
SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL;
|
||||||
Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map;
|
Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map;
|
||||||
ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL;
|
ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL;
|
||||||
|
|
||||||
void ParticlesMaterial::init_shaders() {
|
void ParticlesMaterial::init_shaders() {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
material_mutex = Mutex::create();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dirty_materials = memnew(SelfList<ParticlesMaterial>::List);
|
dirty_materials = memnew(SelfList<ParticlesMaterial>::List);
|
||||||
|
|
||||||
shader_names = memnew(ShaderNames);
|
shader_names = memnew(ShaderNames);
|
||||||
|
@ -107,10 +103,6 @@ void ParticlesMaterial::init_shaders() {
|
||||||
|
|
||||||
void ParticlesMaterial::finish_shaders() {
|
void ParticlesMaterial::finish_shaders() {
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
|
||||||
memdelete(material_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memdelete(dirty_materials);
|
memdelete(dirty_materials);
|
||||||
dirty_materials = NULL;
|
dirty_materials = NULL;
|
||||||
|
|
||||||
|
@ -612,44 +604,28 @@ void ParticlesMaterial::_update_shader() {
|
||||||
|
|
||||||
void ParticlesMaterial::flush_changes() {
|
void ParticlesMaterial::flush_changes() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
while (dirty_materials->first()) {
|
while (dirty_materials->first()) {
|
||||||
|
|
||||||
dirty_materials->first()->self()->_update_shader();
|
dirty_materials->first()->self()->_update_shader();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticlesMaterial::_queue_shader_change() {
|
void ParticlesMaterial::_queue_shader_change() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
if (!element.in_list()) {
|
if (!element.in_list()) {
|
||||||
dirty_materials->add(&element);
|
dirty_materials->add(&element);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParticlesMaterial::_is_shader_dirty() const {
|
bool ParticlesMaterial::_is_shader_dirty() const {
|
||||||
|
|
||||||
bool dirty = false;
|
MutexLock lock(material_mutex);
|
||||||
|
|
||||||
if (material_mutex)
|
return element.in_list();
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
dirty = element.in_list();
|
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
|
|
||||||
return dirty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticlesMaterial::set_direction(Vector3 p_direction) {
|
void ParticlesMaterial::set_direction(Vector3 p_direction) {
|
||||||
|
@ -1298,8 +1274,7 @@ ParticlesMaterial::ParticlesMaterial() :
|
||||||
|
|
||||||
ParticlesMaterial::~ParticlesMaterial() {
|
ParticlesMaterial::~ParticlesMaterial() {
|
||||||
|
|
||||||
if (material_mutex)
|
MutexLock lock(material_mutex);
|
||||||
material_mutex->lock();
|
|
||||||
|
|
||||||
if (shader_map.has(current_key)) {
|
if (shader_map.has(current_key)) {
|
||||||
shader_map[current_key].users--;
|
shader_map[current_key].users--;
|
||||||
|
@ -1311,7 +1286,4 @@ ParticlesMaterial::~ParticlesMaterial() {
|
||||||
|
|
||||||
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material_mutex)
|
|
||||||
material_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ private:
|
||||||
return mk;
|
return mk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mutex *material_mutex;
|
static Mutex material_mutex;
|
||||||
static SelfList<ParticlesMaterial>::List *dirty_materials;
|
static SelfList<ParticlesMaterial>::List *dirty_materials;
|
||||||
|
|
||||||
struct ShaderNames {
|
struct ShaderNames {
|
||||||
|
|
|
@ -49,7 +49,6 @@ Error AudioDriverDummy::init() {
|
||||||
|
|
||||||
samples_in = memnew_arr(int32_t, buffer_frames * channels);
|
samples_in = memnew_arr(int32_t, buffer_frames * channels);
|
||||||
|
|
||||||
mutex = Mutex::create();
|
|
||||||
thread = Thread::create(AudioDriverDummy::thread_func, this);
|
thread = Thread::create(AudioDriverDummy::thread_func, this);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -95,16 +94,16 @@ AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const {
|
||||||
|
|
||||||
void AudioDriverDummy::lock() {
|
void AudioDriverDummy::lock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->lock();
|
mutex.lock();
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioDriverDummy::unlock() {
|
void AudioDriverDummy::unlock() {
|
||||||
|
|
||||||
if (!thread || !mutex)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
mutex->unlock();
|
mutex.unlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioDriverDummy::finish() {
|
void AudioDriverDummy::finish() {
|
||||||
|
@ -120,14 +119,11 @@ void AudioDriverDummy::finish() {
|
||||||
};
|
};
|
||||||
|
|
||||||
memdelete(thread);
|
memdelete(thread);
|
||||||
if (mutex)
|
|
||||||
memdelete(mutex);
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioDriverDummy::AudioDriverDummy() {
|
AudioDriverDummy::AudioDriverDummy() {
|
||||||
|
|
||||||
mutex = NULL;
|
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
class AudioDriverDummy : public AudioDriver {
|
class AudioDriverDummy : public AudioDriver {
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
Mutex *mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
int32_t *samples_in;
|
int32_t *samples_in;
|
||||||
|
|
||||||
|
|
|
@ -1137,27 +1137,28 @@ void *AudioServer::audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_d
|
||||||
copymem(ad, p_from_data, p_data_len);
|
copymem(ad, p_from_data, p_data_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_data_lock->lock();
|
{
|
||||||
|
MutexLock lock(audio_data_lock);
|
||||||
|
|
||||||
audio_data[ad] = p_data_len;
|
audio_data[ad] = p_data_len;
|
||||||
audio_data_total_mem += p_data_len;
|
audio_data_total_mem += p_data_len;
|
||||||
audio_data_max_mem = MAX(audio_data_total_mem, audio_data_max_mem);
|
audio_data_max_mem = MAX(audio_data_total_mem, audio_data_max_mem);
|
||||||
audio_data_lock->unlock();
|
}
|
||||||
|
|
||||||
return ad;
|
return ad;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioServer::audio_data_free(void *p_data) {
|
void AudioServer::audio_data_free(void *p_data) {
|
||||||
|
|
||||||
audio_data_lock->lock();
|
MutexLock lock(audio_data_lock);
|
||||||
|
|
||||||
if (!audio_data.has(p_data)) {
|
if (!audio_data.has(p_data)) {
|
||||||
audio_data_lock->unlock();
|
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_data_total_mem -= audio_data[p_data];
|
audio_data_total_mem -= audio_data[p_data];
|
||||||
audio_data.erase(p_data);
|
audio_data.erase(p_data);
|
||||||
memfree(p_data);
|
memfree(p_data);
|
||||||
audio_data_lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioServer::audio_data_get_total_memory_usage() const {
|
size_t AudioServer::audio_data_get_total_memory_usage() const {
|
||||||
|
@ -1399,7 +1400,6 @@ AudioServer::AudioServer() {
|
||||||
singleton = this;
|
singleton = this;
|
||||||
audio_data_total_mem = 0;
|
audio_data_total_mem = 0;
|
||||||
audio_data_max_mem = 0;
|
audio_data_max_mem = 0;
|
||||||
audio_data_lock = Mutex::create();
|
|
||||||
mix_frames = 0;
|
mix_frames = 0;
|
||||||
channel_count = 0;
|
channel_count = 0;
|
||||||
to_mix = 0;
|
to_mix = 0;
|
||||||
|
@ -1413,7 +1413,6 @@ AudioServer::AudioServer() {
|
||||||
|
|
||||||
AudioServer::~AudioServer() {
|
AudioServer::~AudioServer() {
|
||||||
|
|
||||||
memdelete(audio_data_lock);
|
|
||||||
singleton = NULL;
|
singleton = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,7 @@ private:
|
||||||
size_t audio_data_total_mem;
|
size_t audio_data_total_mem;
|
||||||
size_t audio_data_max_mem;
|
size_t audio_data_max_mem;
|
||||||
|
|
||||||
Mutex *audio_data_lock;
|
Mutex audio_data_lock;
|
||||||
|
|
||||||
void init_channels_and_buffers();
|
void init_channels_and_buffers();
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,6 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool
|
||||||
step_sem = NULL;
|
step_sem = NULL;
|
||||||
step_pending = 0;
|
step_pending = 0;
|
||||||
step_thread_up = false;
|
step_thread_up = false;
|
||||||
alloc_mutex = Mutex::create();
|
|
||||||
|
|
||||||
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
|
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
|
||||||
|
|
||||||
|
@ -177,6 +176,5 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool
|
||||||
Physics2DServerWrapMT::~Physics2DServerWrapMT() {
|
Physics2DServerWrapMT::~Physics2DServerWrapMT() {
|
||||||
|
|
||||||
memdelete(physics_2d_server);
|
memdelete(physics_2d_server);
|
||||||
memdelete(alloc_mutex);
|
|
||||||
//finish();
|
//finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ class Physics2DServerWrapMT : public Physics2DServer {
|
||||||
|
|
||||||
bool first_frame;
|
bool first_frame;
|
||||||
|
|
||||||
Mutex *alloc_mutex;
|
Mutex alloc_mutex;
|
||||||
int pool_max_size;
|
int pool_max_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
virtual RID m_type##_create() { \
|
virtual RID m_type##_create() { \
|
||||||
if (Thread::get_caller_id() != server_thread) { \
|
if (Thread::get_caller_id() != server_thread) { \
|
||||||
RID rid; \
|
RID rid; \
|
||||||
alloc_mutex->lock(); \
|
MutexLock lock(alloc_mutex); \
|
||||||
if (m_type##_id_pool.size() == 0) { \
|
if (m_type##_id_pool.size() == 0) { \
|
||||||
int ret; \
|
int ret; \
|
||||||
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \
|
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \
|
||||||
|
@ -65,7 +65,6 @@
|
||||||
} \
|
} \
|
||||||
rid = m_type##_id_pool.front()->get(); \
|
rid = m_type##_id_pool.front()->get(); \
|
||||||
m_type##_id_pool.pop_front(); \
|
m_type##_id_pool.pop_front(); \
|
||||||
alloc_mutex->unlock(); \
|
|
||||||
return rid; \
|
return rid; \
|
||||||
} else { \
|
} else { \
|
||||||
return server_name->m_type##_create(); \
|
return server_name->m_type##_create(); \
|
||||||
|
@ -88,7 +87,7 @@
|
||||||
virtual RID m_type##_create(m_arg1 p1) { \
|
virtual RID m_type##_create(m_arg1 p1) { \
|
||||||
if (Thread::get_caller_id() != server_thread) { \
|
if (Thread::get_caller_id() != server_thread) { \
|
||||||
RID rid; \
|
RID rid; \
|
||||||
alloc_mutex->lock(); \
|
MutexLock lock(alloc_mutex); \
|
||||||
if (m_type##_id_pool.size() == 0) { \
|
if (m_type##_id_pool.size() == 0) { \
|
||||||
int ret; \
|
int ret; \
|
||||||
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \
|
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \
|
||||||
|
@ -96,7 +95,6 @@
|
||||||
} \
|
} \
|
||||||
rid = m_type##_id_pool.front()->get(); \
|
rid = m_type##_id_pool.front()->get(); \
|
||||||
m_type##_id_pool.pop_front(); \
|
m_type##_id_pool.pop_front(); \
|
||||||
alloc_mutex->unlock(); \
|
|
||||||
return rid; \
|
return rid; \
|
||||||
} else { \
|
} else { \
|
||||||
return server_name->m_type##_create(p1); \
|
return server_name->m_type##_create(p1); \
|
||||||
|
@ -119,7 +117,7 @@
|
||||||
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \
|
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \
|
||||||
if (Thread::get_caller_id() != server_thread) { \
|
if (Thread::get_caller_id() != server_thread) { \
|
||||||
RID rid; \
|
RID rid; \
|
||||||
alloc_mutex->lock(); \
|
MutexLock lock(alloc_mutex); \
|
||||||
if (m_type##_id_pool.size() == 0) { \
|
if (m_type##_id_pool.size() == 0) { \
|
||||||
int ret; \
|
int ret; \
|
||||||
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \
|
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \
|
||||||
|
@ -127,7 +125,6 @@
|
||||||
} \
|
} \
|
||||||
rid = m_type##_id_pool.front()->get(); \
|
rid = m_type##_id_pool.front()->get(); \
|
||||||
m_type##_id_pool.pop_front(); \
|
m_type##_id_pool.pop_front(); \
|
||||||
alloc_mutex->unlock(); \
|
|
||||||
return rid; \
|
return rid; \
|
||||||
} else { \
|
} else { \
|
||||||
return server_name->m_type##_create(p1, p2); \
|
return server_name->m_type##_create(p1, p2); \
|
||||||
|
@ -150,7 +147,7 @@
|
||||||
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
|
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
|
||||||
if (Thread::get_caller_id() != server_thread) { \
|
if (Thread::get_caller_id() != server_thread) { \
|
||||||
RID rid; \
|
RID rid; \
|
||||||
alloc_mutex->lock(); \
|
MutexLock lock(alloc_mutex); \
|
||||||
if (m_type##_id_pool.size() == 0) { \
|
if (m_type##_id_pool.size() == 0) { \
|
||||||
int ret; \
|
int ret; \
|
||||||
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \
|
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \
|
||||||
|
@ -158,7 +155,6 @@
|
||||||
} \
|
} \
|
||||||
rid = m_type##_id_pool.front()->get(); \
|
rid = m_type##_id_pool.front()->get(); \
|
||||||
m_type##_id_pool.pop_front(); \
|
m_type##_id_pool.pop_front(); \
|
||||||
alloc_mutex->unlock(); \
|
|
||||||
return rid; \
|
return rid; \
|
||||||
} else { \
|
} else { \
|
||||||
return server_name->m_type##_create(p1, p2, p3); \
|
return server_name->m_type##_create(p1, p2, p3); \
|
||||||
|
@ -181,7 +177,7 @@
|
||||||
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
|
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
|
||||||
if (Thread::get_caller_id() != server_thread) { \
|
if (Thread::get_caller_id() != server_thread) { \
|
||||||
RID rid; \
|
RID rid; \
|
||||||
alloc_mutex->lock(); \
|
MutexLock lock(alloc_mutex); \
|
||||||
if (m_type##_id_pool.size() == 0) { \
|
if (m_type##_id_pool.size() == 0) { \
|
||||||
int ret; \
|
int ret; \
|
||||||
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \
|
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \
|
||||||
|
@ -189,7 +185,6 @@
|
||||||
} \
|
} \
|
||||||
rid = m_type##_id_pool.front()->get(); \
|
rid = m_type##_id_pool.front()->get(); \
|
||||||
m_type##_id_pool.pop_front(); \
|
m_type##_id_pool.pop_front(); \
|
||||||
alloc_mutex->unlock(); \
|
|
||||||
return rid; \
|
return rid; \
|
||||||
} else { \
|
} else { \
|
||||||
return server_name->m_type##_create(p1, p2, p3, p4); \
|
return server_name->m_type##_create(p1, p2, p3, p4); \
|
||||||
|
@ -213,7 +208,7 @@
|
||||||
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
|
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
|
||||||
if (Thread::get_caller_id() != server_thread) { \
|
if (Thread::get_caller_id() != server_thread) { \
|
||||||
RID rid; \
|
RID rid; \
|
||||||
alloc_mutex->lock(); \
|
MutexLock lock(alloc_mutex); \
|
||||||
if (m_type##_id_pool.size() == 0) { \
|
if (m_type##_id_pool.size() == 0) { \
|
||||||
int ret; \
|
int ret; \
|
||||||
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \
|
command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \
|
||||||
|
@ -221,7 +216,6 @@
|
||||||
} \
|
} \
|
||||||
rid = m_type##_id_pool.front()->get(); \
|
rid = m_type##_id_pool.front()->get(); \
|
||||||
m_type##_id_pool.pop_front(); \
|
m_type##_id_pool.pop_front(); \
|
||||||
alloc_mutex->unlock(); \
|
|
||||||
return rid; \
|
return rid; \
|
||||||
} else { \
|
} else { \
|
||||||
return server_name->m_type##_create(p1, p2, p3, p4, p5); \
|
return server_name->m_type##_create(p1, p2, p3, p4, p5); \
|
||||||
|
|
|
@ -342,23 +342,21 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!build_ok) {
|
if (!build_ok) {
|
||||||
variant_set_mutex.lock(); //properly print the errors
|
MutexLock lock(variant_set_mutex); //properly print the errors
|
||||||
ERR_PRINT("Error compiling " + String(current_stage == RD::SHADER_STAGE_COMPUTE ? "Compute " : (current_stage == RD::SHADER_STAGE_VERTEX ? "Vertex" : "Fragment")) + " shader, variant #" + itos(p_variant) + " (" + variant_defines[p_variant].get_data() + ").");
|
ERR_PRINT("Error compiling " + String(current_stage == RD::SHADER_STAGE_COMPUTE ? "Compute " : (current_stage == RD::SHADER_STAGE_VERTEX ? "Vertex" : "Fragment")) + " shader, variant #" + itos(p_variant) + " (" + variant_defines[p_variant].get_data() + ").");
|
||||||
ERR_PRINT(error);
|
ERR_PRINT(error);
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
ERR_PRINT("code:\n" + current_source.get_with_code_lines());
|
ERR_PRINT("code:\n" + current_source.get_with_code_lines());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
variant_set_mutex.unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RID shader = RD::get_singleton()->shader_create(stages);
|
RID shader = RD::get_singleton()->shader_create(stages);
|
||||||
|
{
|
||||||
variant_set_mutex.lock();
|
MutexLock lock(variant_set_mutex);
|
||||||
p_version->variants[p_variant] = shader;
|
p_version->variants[p_variant] = shader;
|
||||||
variant_set_mutex.unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderRD::_compile_version(Version *p_version) {
|
void ShaderRD::_compile_version(Version *p_version) {
|
||||||
|
|
|
@ -33,11 +33,11 @@
|
||||||
|
|
||||||
#include "core/hash_map.h"
|
#include "core/hash_map.h"
|
||||||
#include "core/map.h"
|
#include "core/map.h"
|
||||||
|
#include "core/os/mutex.h"
|
||||||
#include "core/rid_owner.h"
|
#include "core/rid_owner.h"
|
||||||
#include "core/variant.h"
|
#include "core/variant.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <mutex>
|
|
||||||
/**
|
/**
|
||||||
@author Juan Linietsky <reduzio@gmail.com>
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +66,7 @@ class ShaderRD {
|
||||||
bool initialize_needed;
|
bool initialize_needed;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::mutex variant_set_mutex;
|
Mutex variant_set_mutex;
|
||||||
|
|
||||||
void _compile_variant(uint32_t p_variant, Version *p_version);
|
void _compile_variant(uint32_t p_variant, Version *p_version);
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,6 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
draw_pending = 0;
|
draw_pending = 0;
|
||||||
draw_thread_up = false;
|
draw_thread_up = false;
|
||||||
alloc_mutex = Mutex::create();
|
|
||||||
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
|
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
|
||||||
|
|
||||||
if (!p_create_thread) {
|
if (!p_create_thread) {
|
||||||
|
@ -193,6 +192,5 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_
|
||||||
VisualServerWrapMT::~VisualServerWrapMT() {
|
VisualServerWrapMT::~VisualServerWrapMT() {
|
||||||
|
|
||||||
memdelete(visual_server);
|
memdelete(visual_server);
|
||||||
memdelete(alloc_mutex);
|
|
||||||
//finish();
|
//finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ class VisualServerWrapMT : public VisualServer {
|
||||||
|
|
||||||
void thread_exit();
|
void thread_exit();
|
||||||
|
|
||||||
Mutex *alloc_mutex;
|
Mutex alloc_mutex;
|
||||||
|
|
||||||
int pool_max_size;
|
int pool_max_size;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue