Fixed the IP resolver code blocking the main thread, it uses a Mutex now to lock its own thread.
This commit is contained in:
parent
ce6bae1716
commit
bba8f1db30
1 changed files with 47 additions and 18 deletions
|
@ -68,6 +68,7 @@ struct _IP_ResolverPrivate {
|
||||||
return IP::RESOLVER_INVALID_ID;
|
return IP::RESOLVER_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mutex *mutex;
|
||||||
Semaphore *sem;
|
Semaphore *sem;
|
||||||
|
|
||||||
Thread *thread;
|
Thread *thread;
|
||||||
|
@ -96,8 +97,10 @@ struct _IP_ResolverPrivate {
|
||||||
while (!ipr->thread_abort) {
|
while (!ipr->thread_abort) {
|
||||||
|
|
||||||
ipr->sem->wait();
|
ipr->sem->wait();
|
||||||
GLOBAL_LOCK_FUNCTION;
|
|
||||||
|
ipr->mutex->lock();
|
||||||
ipr->resolve_queues();
|
ipr->resolve_queues();
|
||||||
|
ipr->mutex->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,24 +113,30 @@ 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) {
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
resolver->mutex->lock();
|
||||||
|
|
||||||
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))
|
if (resolver->cache.has(key)) {
|
||||||
return resolver->cache[key];
|
IP_Address res = resolver->cache[key];
|
||||||
|
resolver->mutex->unlock();
|
||||||
|
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) {
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
resolver->mutex->lock();
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +155,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,35 +163,51 @@ 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);
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
resolver->mutex->lock();
|
||||||
ERR_FAIL_COND_V(resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE, IP::RESOLVER_STATUS_NONE);
|
if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) {
|
||||||
|
ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
|
||||||
|
resolver->mutex->unlock();
|
||||||
|
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());
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
resolver->mutex->lock();
|
||||||
|
|
||||||
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
|
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
|
||||||
ERR_EXPLAIN("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
|
ERR_PRINTS("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
|
||||||
ERR_FAIL_COND_V(resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE, IP_Address());
|
resolver->mutex->unlock();
|
||||||
|
return IP_Address();
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolver->queue[p_id].response;
|
IP_Address res = 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);
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
resolver->mutex->lock();
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
if (p_hostname.empty()) {
|
if (p_hostname.empty()) {
|
||||||
resolver->cache.clear();
|
resolver->cache.clear();
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,7 +216,9 @@ 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 {
|
||||||
|
|
||||||
|
@ -249,12 +277,11 @@ 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
|
||||||
|
|
||||||
//resolver->sem = Semaphore::create();
|
resolver->sem = Semaphore::create();
|
||||||
|
|
||||||
resolver->sem = NULL;
|
|
||||||
if (resolver->sem) {
|
if (resolver->sem) {
|
||||||
resolver->thread_abort = false;
|
resolver->thread_abort = false;
|
||||||
|
|
||||||
|
@ -281,7 +308,9 @@ IP::~IP() {
|
||||||
memdelete(resolver->thread);
|
memdelete(resolver->thread);
|
||||||
memdelete(resolver->sem);
|
memdelete(resolver->sem);
|
||||||
}
|
}
|
||||||
memdelete(resolver);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
memdelete(resolver->mutex);
|
||||||
|
memdelete(resolver);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue