Remove NO_THREADS fallback code, Godot 4 requires thread support
This also removes `OS::can_use_threads` from the public API since it's always true.
This commit is contained in:
parent
d331b803b8
commit
54418ea659
|
@ -425,10 +425,6 @@ void OS::delay_msec(int p_msec) const {
|
|||
::OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000);
|
||||
}
|
||||
|
||||
bool OS::can_use_threads() const {
|
||||
return ::OS::get_singleton()->can_use_threads();
|
||||
}
|
||||
|
||||
bool OS::is_userfs_persistent() const {
|
||||
return ::OS::get_singleton()->is_userfs_persistent();
|
||||
}
|
||||
|
@ -561,8 +557,6 @@ void OS::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &OS::is_userfs_persistent);
|
||||
ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &OS::is_stdout_verbose);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("can_use_threads"), &OS::can_use_threads);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_debug_build"), &OS::is_debug_build);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_static_memory_usage"), &OS::get_static_memory_usage);
|
||||
|
|
|
@ -218,8 +218,6 @@ public:
|
|||
uint64_t get_ticks_msec() const;
|
||||
uint64_t get_ticks_usec() const;
|
||||
|
||||
bool can_use_threads() const;
|
||||
|
||||
bool is_userfs_persistent() const;
|
||||
|
||||
bool is_stdout_verbose() const;
|
||||
|
|
|
@ -79,10 +79,8 @@ RemoteDebuggerPeerTCP::RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_tcp) {
|
|||
tcp_client = p_tcp;
|
||||
if (tcp_client.is_valid()) { // Attaching to an already connected stream.
|
||||
connected = true;
|
||||
#ifndef NO_THREADS
|
||||
running = true;
|
||||
thread.start(_thread_func, this);
|
||||
#endif
|
||||
} else {
|
||||
tcp_client.instantiate();
|
||||
}
|
||||
|
@ -183,10 +181,8 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
|
|||
return FAILED;
|
||||
}
|
||||
connected = true;
|
||||
#ifndef NO_THREADS
|
||||
running = true;
|
||||
thread.start(_thread_func, this);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -208,9 +204,7 @@ void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
|
|||
}
|
||||
|
||||
void RemoteDebuggerPeerTCP::poll() {
|
||||
#ifdef NO_THREADS
|
||||
_poll();
|
||||
#endif
|
||||
// Nothing to do, polling is done in thread.
|
||||
}
|
||||
|
||||
void RemoteDebuggerPeerTCP::_poll() {
|
||||
|
|
|
@ -43,12 +43,12 @@ protected:
|
|||
|
||||
public:
|
||||
virtual bool is_peer_connected() = 0;
|
||||
virtual int get_max_message_size() const = 0;
|
||||
virtual bool has_message() = 0;
|
||||
virtual Error put_message(const Array &p_arr) = 0;
|
||||
virtual Array get_message() = 0;
|
||||
virtual void close() = 0;
|
||||
virtual void poll() = 0;
|
||||
virtual int get_max_message_size() const = 0;
|
||||
virtual bool can_block() const { return true; } // If blocking io is allowed on main thread (debug).
|
||||
|
||||
RemoteDebuggerPeer();
|
||||
|
@ -81,12 +81,12 @@ public:
|
|||
|
||||
Error connect_to_host(const String &p_host, uint16_t p_port);
|
||||
|
||||
void poll() override;
|
||||
bool is_peer_connected() override;
|
||||
bool has_message() override;
|
||||
Array get_message() override;
|
||||
Error put_message(const Array &p_arr) override;
|
||||
int get_max_message_size() const override;
|
||||
bool has_message() override;
|
||||
Error put_message(const Array &p_arr) override;
|
||||
Array get_message() override;
|
||||
void poll() override;
|
||||
void close() override;
|
||||
|
||||
RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_stream = Ref<StreamPeerTCP>());
|
||||
|
|
|
@ -40,11 +40,7 @@ void _global_unlock() {
|
|||
_global_mutex.unlock();
|
||||
}
|
||||
|
||||
#ifndef NO_THREADS
|
||||
|
||||
template class MutexImpl<std::recursive_mutex>;
|
||||
template class MutexImpl<std::mutex>;
|
||||
template class MutexLock<MutexImpl<std::recursive_mutex>>;
|
||||
template class MutexLock<MutexImpl<std::mutex>>;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "core/error/error_list.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
#include <mutex>
|
||||
|
||||
template <class StdMutexT>
|
||||
|
@ -79,29 +77,4 @@ extern template class MutexImpl<std::mutex>;
|
|||
extern template class MutexLock<MutexImpl<std::recursive_mutex>>;
|
||||
extern template class MutexLock<MutexImpl<std::mutex>>;
|
||||
|
||||
#else
|
||||
|
||||
class FakeMutex {
|
||||
FakeMutex() {}
|
||||
};
|
||||
|
||||
template <class MutexT>
|
||||
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) {}
|
||||
};
|
||||
|
||||
using Mutex = MutexImpl<FakeMutex>;
|
||||
using BinaryMutex = MutexImpl<FakeMutex>; // Non-recursive, handle with care
|
||||
|
||||
#endif // !NO_THREADS
|
||||
|
||||
#endif // MUTEX_H
|
||||
|
|
|
@ -328,14 +328,6 @@ String OS::get_processor_name() const {
|
|||
return "";
|
||||
}
|
||||
|
||||
bool OS::can_use_threads() const {
|
||||
#ifdef NO_THREADS
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) {
|
||||
has_server_feature_callback = p_callback;
|
||||
}
|
||||
|
|
|
@ -299,8 +299,6 @@ public:
|
|||
|
||||
virtual String get_unique_id() const;
|
||||
|
||||
virtual bool can_use_threads() const;
|
||||
|
||||
bool has_feature(const String &p_feature);
|
||||
|
||||
void set_has_server_feature_callback(HasServerFeatureCallback p_callback);
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
#include "core/error/error_list.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
class RWLock {
|
||||
|
@ -72,21 +70,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class RWLock {
|
||||
public:
|
||||
void read_lock() const {}
|
||||
void read_unlock() const {}
|
||||
Error read_try_lock() const { return OK; }
|
||||
|
||||
void write_lock() {}
|
||||
void write_unlock() {}
|
||||
Error write_try_lock() { return OK; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class RWLockRead {
|
||||
const RWLock &lock;
|
||||
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "core/error/error_list.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
|
@ -70,15 +68,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class Semaphore {
|
||||
public:
|
||||
_ALWAYS_INLINE_ void post() const {}
|
||||
_ALWAYS_INLINE_ void wait() const {}
|
||||
_ALWAYS_INLINE_ bool try_wait() const { return true; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SEMAPHORE_H
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
#include "thread.h"
|
||||
|
||||
#include "core/object/script_language.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
#include "core/templates/safe_refcount.h"
|
||||
|
||||
Error (*Thread::set_name_func)(const String &) = nullptr;
|
||||
|
@ -128,5 +125,4 @@ Thread::~Thread() {
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // PLATFORM_THREAD_OVERRIDE
|
||||
|
|
|
@ -35,15 +35,14 @@
|
|||
#ifdef PLATFORM_THREAD_OVERRIDE
|
||||
#include "platform_thread.h"
|
||||
#else
|
||||
|
||||
#ifndef THREAD_H
|
||||
#define THREAD_H
|
||||
|
||||
#include "core/templates/safe_refcount.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
#include "core/templates/safe_refcount.h"
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
class String;
|
||||
|
||||
|
@ -65,7 +64,6 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
#if !defined(NO_THREADS)
|
||||
friend class Main;
|
||||
|
||||
static ID main_thread_id;
|
||||
|
@ -82,7 +80,6 @@ private:
|
|||
static void (*set_priority_func)(Thread::Priority);
|
||||
static void (*init_func)();
|
||||
static void (*term_func)();
|
||||
#endif
|
||||
|
||||
public:
|
||||
static void _set_platform_funcs(
|
||||
|
@ -91,7 +88,6 @@ public:
|
|||
void (*p_init_func)() = nullptr,
|
||||
void (*p_term_func)() = nullptr);
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
_FORCE_INLINE_ ID get_id() const { return id; }
|
||||
// get the ID of the caller thread
|
||||
_FORCE_INLINE_ static ID get_caller_id() { return caller_id; }
|
||||
|
@ -107,19 +103,6 @@ public:
|
|||
|
||||
Thread();
|
||||
~Thread();
|
||||
#else
|
||||
_FORCE_INLINE_ ID get_id() const { return 0; }
|
||||
// get the ID of the caller thread
|
||||
_FORCE_INLINE_ static ID get_caller_id() { return 0; }
|
||||
// get the ID of the main thread
|
||||
_FORCE_INLINE_ static ID get_main_id() { return 0; }
|
||||
|
||||
static Error set_name(const String &p_name) { return ERR_UNAVAILABLE; }
|
||||
|
||||
void start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings()) {}
|
||||
bool is_started() const { return false; }
|
||||
void wait_to_finish() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // THREAD_H
|
||||
|
|
|
@ -49,8 +49,6 @@ struct ThreadArrayProcessData {
|
|||
}
|
||||
};
|
||||
|
||||
#ifndef NO_THREADS
|
||||
|
||||
template <class T>
|
||||
void process_array_thread(void *ud) {
|
||||
T &data = *(T *)ud;
|
||||
|
@ -86,21 +84,4 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
|
|||
memdelete_arr(threads);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class C, class M, class U>
|
||||
void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
|
||||
ThreadArrayProcessData<C, U> data;
|
||||
data.method = p_method;
|
||||
data.instance = p_instance;
|
||||
data.userdata = p_userdata;
|
||||
data.index.set(0);
|
||||
data.elements = p_elements;
|
||||
for (uint32_t i = 0; i < p_elements; i++) {
|
||||
data.process(i);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // THREADED_ARRAY_PROCESSOR_H
|
||||
|
|
|
@ -46,9 +46,7 @@ class CharString;
|
|||
template <class T, class V>
|
||||
class VMap;
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t)
|
||||
#endif
|
||||
|
||||
// Silence a false positive warning (see GH-52119).
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
|
|
|
@ -33,11 +33,9 @@
|
|||
|
||||
#include "core/os/memory.h"
|
||||
#include "core/typedefs.h"
|
||||
#include <functional>
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
// Design goals for these classes:
|
||||
|
@ -239,159 +237,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#else // NO_THREADS
|
||||
|
||||
// Effectively the same structure without the atomics. It's probably possible to simplify it but the semantics shouldn't differ greatly.
|
||||
template <class T, class A = DefaultAllocator>
|
||||
class SafeList {
|
||||
struct SafeListNode {
|
||||
SafeListNode *next = nullptr;
|
||||
|
||||
// If the node is logically deleted, this pointer will typically point to the previous list item in time that was also logically deleted.
|
||||
SafeListNode *graveyard_next = nullptr;
|
||||
|
||||
std::function<void(T)> deletion_fn = [](T t) { return; };
|
||||
|
||||
T val;
|
||||
};
|
||||
|
||||
SafeListNode *head = nullptr;
|
||||
SafeListNode *graveyard_head = nullptr;
|
||||
|
||||
unsigned int active_iterator_count = 0;
|
||||
|
||||
public:
|
||||
class Iterator {
|
||||
friend class SafeList;
|
||||
|
||||
SafeListNode *cursor = nullptr;
|
||||
SafeList *list = nullptr;
|
||||
|
||||
public:
|
||||
Iterator(SafeListNode *p_cursor, SafeList *p_list) :
|
||||
cursor(p_cursor), list(p_list) {
|
||||
list->active_iterator_count++;
|
||||
}
|
||||
|
||||
~Iterator() {
|
||||
list->active_iterator_count--;
|
||||
}
|
||||
|
||||
T &operator*() {
|
||||
return cursor->val;
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
cursor = cursor->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// These two operators are mostly useful for comparisons to nullptr.
|
||||
bool operator==(const void *p_other) const {
|
||||
return cursor == p_other;
|
||||
}
|
||||
|
||||
bool operator!=(const void *p_other) const {
|
||||
return cursor != p_other;
|
||||
}
|
||||
|
||||
// These two allow easy range-based for loops.
|
||||
bool operator==(const Iterator &p_other) const {
|
||||
return cursor == p_other.cursor;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &p_other) const {
|
||||
return cursor != p_other.cursor;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
// Calling this will cause an allocation.
|
||||
void insert(T p_value) {
|
||||
SafeListNode *new_node = memnew_allocator(SafeListNode, A);
|
||||
new_node->val = p_value;
|
||||
new_node->next = head;
|
||||
head = new_node;
|
||||
}
|
||||
|
||||
Iterator find(T p_value) {
|
||||
for (Iterator it = begin(); it != end(); ++it) {
|
||||
if (*it == p_value) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
void erase(T p_value, std::function<void(T)> p_deletion_fn) {
|
||||
erase(find(p_value), p_deletion_fn);
|
||||
}
|
||||
|
||||
void erase(T p_value) {
|
||||
erase(find(p_value), [](T t) { return; });
|
||||
}
|
||||
|
||||
void erase(Iterator p_iterator, std::function<void(T)> p_deletion_fn) {
|
||||
p_iterator.cursor->deletion_fn = p_deletion_fn;
|
||||
erase(p_iterator);
|
||||
}
|
||||
|
||||
void erase(Iterator p_iterator) {
|
||||
Iterator prev = begin();
|
||||
for (; prev != end(); ++prev) {
|
||||
if (prev.cursor && prev.cursor->next == p_iterator.cursor) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prev == end()) {
|
||||
// Not in the list, nothing to do.
|
||||
return;
|
||||
}
|
||||
// First, remove the node from the list.
|
||||
prev.cursor->next = p_iterator.cursor->next;
|
||||
|
||||
// Then queue it for deletion by putting it in the node graveyard. Don't touch `next` because an iterator might still be pointing at this node.
|
||||
p_iterator.cursor->graveyard_next = graveyard_head;
|
||||
graveyard_head = p_iterator.cursor;
|
||||
}
|
||||
|
||||
Iterator begin() {
|
||||
return Iterator(head, this);
|
||||
}
|
||||
|
||||
Iterator end() {
|
||||
return Iterator(nullptr, this);
|
||||
}
|
||||
|
||||
// Calling this will cause zero to many deallocations.
|
||||
bool maybe_cleanup() {
|
||||
SafeListNode *cursor = graveyard_head;
|
||||
if (active_iterator_count != 0) {
|
||||
// It's not safe to clean up with an active iterator, because that iterator could be pointing to an element that we want to delete.
|
||||
return false;
|
||||
}
|
||||
graveyard_head = nullptr;
|
||||
// Our graveyard list is now unreachable by any active iterators, detached from the main graveyard head and ready for deletion.
|
||||
while (cursor) {
|
||||
SafeListNode *tmp = cursor;
|
||||
cursor = cursor->next;
|
||||
tmp->deletion_fn(tmp->val);
|
||||
memdelete_allocator<SafeListNode, A>(tmp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
~SafeList() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (!maybe_cleanup()) {
|
||||
ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug.");
|
||||
}
|
||||
#else
|
||||
maybe_cleanup();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SAFE_LIST_H
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
|
||||
|
@ -191,141 +189,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
class SafeNumeric {
|
||||
protected:
|
||||
T value;
|
||||
|
||||
public:
|
||||
_ALWAYS_INLINE_ void set(T p_value) {
|
||||
value = p_value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T get() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T increment() {
|
||||
return ++value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T postincrement() {
|
||||
return value++;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T decrement() {
|
||||
return --value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T postdecrement() {
|
||||
return value--;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T add(T p_value) {
|
||||
return value += p_value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T postadd(T p_value) {
|
||||
T old = value;
|
||||
value += p_value;
|
||||
return old;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T sub(T p_value) {
|
||||
return value -= p_value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T postsub(T p_value) {
|
||||
T old = value;
|
||||
value -= p_value;
|
||||
return old;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T exchange_if_greater(T p_value) {
|
||||
if (value < p_value) {
|
||||
value = p_value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ T conditional_increment() {
|
||||
if (value == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return ++value;
|
||||
}
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) :
|
||||
value(p_value) {
|
||||
}
|
||||
};
|
||||
|
||||
class SafeFlag {
|
||||
protected:
|
||||
bool flag;
|
||||
|
||||
public:
|
||||
_ALWAYS_INLINE_ bool is_set() const {
|
||||
return flag;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ void set() {
|
||||
flag = true;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ void clear() {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ void set_to(bool p_value) {
|
||||
flag = p_value;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ explicit SafeFlag(bool p_value = false) :
|
||||
flag(p_value) {}
|
||||
};
|
||||
|
||||
class SafeRefCount {
|
||||
uint32_t count = 0;
|
||||
|
||||
public:
|
||||
_ALWAYS_INLINE_ bool ref() { // true on success
|
||||
if (count != 0) {
|
||||
++count;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ uint32_t refval() { // none-zero on success
|
||||
if (count != 0) {
|
||||
return ++count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ bool unref() { // true if must be disposed of
|
||||
return --count == 0;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of
|
||||
return --count;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ uint32_t get() const {
|
||||
return count;
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ void init(uint32_t p_value = 1) {
|
||||
count = p_value;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SAFE_REFCOUNT_H
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
Displays a modal dialog box using the host OS' facilities. Execution is blocked until the dialog is closed.
|
||||
</description>
|
||||
</method>
|
||||
<method name="can_use_threads" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Returns [code]true[/code] if the current host platform is using multiple threads.
|
||||
</description>
|
||||
</method>
|
||||
<method name="close_midi_inputs">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
|
|
@ -126,9 +126,7 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) {
|
|||
}
|
||||
|
||||
void OS_Unix::initialize_core() {
|
||||
#if !defined(NO_THREADS)
|
||||
init_thread_posix();
|
||||
#endif
|
||||
|
||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
|
||||
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
|
||||
|
||||
#include "thread_posix.h"
|
||||
|
||||
|
@ -73,4 +73,4 @@ void init_thread_posix() {
|
|||
Thread::_set_platform_funcs(&set_name, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // UNIX_ENABLED || PTHREAD_ENABLED
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#ifndef THREAD_POSIX_H
|
||||
#define THREAD_POSIX_H
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
void init_thread_posix();
|
||||
#endif
|
||||
|
||||
#endif // THREAD_POSIX_H
|
||||
|
|
|
@ -1706,13 +1706,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||
}
|
||||
|
||||
if (rtm >= 0 && rtm < 3) {
|
||||
#ifdef NO_THREADS
|
||||
rtm = OS::RENDER_THREAD_UNSAFE; // No threads available on this platform.
|
||||
#else
|
||||
if (editor) {
|
||||
rtm = OS::RENDER_THREAD_SAFE;
|
||||
}
|
||||
#endif
|
||||
OS::get_singleton()->_render_thread_mode = OS::RenderThreadMode(rtm);
|
||||
}
|
||||
|
||||
|
@ -1932,11 +1928,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
|||
// Print engine name and version
|
||||
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
if (p_main_tid_override) {
|
||||
Thread::main_thread_id = p_main_tid_override;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (editor || project_manager || cmdline_tool) {
|
||||
|
|
|
@ -197,9 +197,6 @@ void NoiseTexture2D::_update_texture() {
|
|||
use_thread = false;
|
||||
first_time = false;
|
||||
}
|
||||
#ifdef NO_THREADS
|
||||
use_thread = false;
|
||||
#endif
|
||||
if (use_thread) {
|
||||
if (!noise_thread.is_started()) {
|
||||
noise_thread.start(_thread_function, this);
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
static RemoteDebuggerPeer *create(const String &p_uri);
|
||||
|
||||
Error connect_to_host(const String &p_uri);
|
||||
|
||||
bool is_peer_connected() override;
|
||||
int get_max_message_size() const override;
|
||||
bool has_message() override;
|
||||
|
|
|
@ -184,51 +184,6 @@ Error AudioDriverWeb::capture_stop() {
|
|||
return OK;
|
||||
}
|
||||
|
||||
#ifdef NO_THREADS
|
||||
/// ScriptProcessorNode implementation
|
||||
AudioDriverScriptProcessor *AudioDriverScriptProcessor::singleton = nullptr;
|
||||
|
||||
void AudioDriverScriptProcessor::_process_callback() {
|
||||
AudioDriverScriptProcessor::singleton->_audio_driver_capture();
|
||||
AudioDriverScriptProcessor::singleton->_audio_driver_process();
|
||||
}
|
||||
|
||||
Error AudioDriverScriptProcessor::create(int &p_buffer_samples, int p_channels) {
|
||||
if (!godot_audio_has_script_processor()) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
return (Error)godot_audio_script_create(&p_buffer_samples, p_channels);
|
||||
}
|
||||
|
||||
void AudioDriverScriptProcessor::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
|
||||
godot_audio_script_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, &_process_callback);
|
||||
}
|
||||
|
||||
/// AudioWorkletNode implementation (no threads)
|
||||
AudioDriverWorklet *AudioDriverWorklet::singleton = nullptr;
|
||||
|
||||
Error AudioDriverWorklet::create(int &p_buffer_size, int p_channels) {
|
||||
if (!godot_audio_has_worklet()) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
return (Error)godot_audio_worklet_create(p_channels);
|
||||
}
|
||||
|
||||
void AudioDriverWorklet::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
|
||||
_audio_driver_process();
|
||||
godot_audio_worklet_start_no_threads(p_out_buf, p_out_buf_size, &_process_callback, p_in_buf, p_in_buf_size, &_capture_callback);
|
||||
}
|
||||
|
||||
void AudioDriverWorklet::_process_callback(int p_pos, int p_samples) {
|
||||
AudioDriverWorklet *driver = AudioDriverWorklet::singleton;
|
||||
driver->_audio_driver_process(p_pos, p_samples);
|
||||
}
|
||||
|
||||
void AudioDriverWorklet::_capture_callback(int p_pos, int p_samples) {
|
||||
AudioDriverWorklet *driver = AudioDriverWorklet::singleton;
|
||||
driver->_audio_driver_capture(p_pos, p_samples);
|
||||
}
|
||||
#else
|
||||
/// AudioWorkletNode implementation (threads)
|
||||
void AudioDriverWorklet::_audio_thread_func(void *p_data) {
|
||||
AudioDriverWorklet *driver = static_cast<AudioDriverWorklet *>(p_data);
|
||||
|
@ -290,4 +245,3 @@ void AudioDriverWorklet::finish_driver() {
|
|||
quit = true; // Ask thread to quit.
|
||||
thread.wait_to_finish();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -89,46 +89,6 @@ public:
|
|||
AudioDriverWeb() {}
|
||||
};
|
||||
|
||||
#ifdef NO_THREADS
|
||||
class AudioDriverScriptProcessor : public AudioDriverWeb {
|
||||
private:
|
||||
static void _process_callback();
|
||||
|
||||
static AudioDriverScriptProcessor *singleton;
|
||||
|
||||
protected:
|
||||
Error create(int &p_buffer_samples, int p_channels) override;
|
||||
void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override;
|
||||
|
||||
public:
|
||||
virtual const char *get_name() const override { return "ScriptProcessor"; }
|
||||
|
||||
virtual void lock() override {}
|
||||
virtual void unlock() override {}
|
||||
|
||||
AudioDriverScriptProcessor() { singleton = this; }
|
||||
};
|
||||
|
||||
class AudioDriverWorklet : public AudioDriverWeb {
|
||||
private:
|
||||
static void _process_callback(int p_pos, int p_samples);
|
||||
static void _capture_callback(int p_pos, int p_samples);
|
||||
|
||||
static AudioDriverWorklet *singleton;
|
||||
|
||||
protected:
|
||||
virtual Error create(int &p_buffer_size, int p_output_channels) override;
|
||||
virtual void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override;
|
||||
|
||||
public:
|
||||
virtual const char *get_name() const override { return "AudioWorklet"; }
|
||||
|
||||
virtual void lock() override {}
|
||||
virtual void unlock() override {}
|
||||
|
||||
AudioDriverWorklet() { singleton = this; }
|
||||
};
|
||||
#else
|
||||
class AudioDriverWorklet : public AudioDriverWeb {
|
||||
private:
|
||||
enum {
|
||||
|
@ -156,6 +116,5 @@ public:
|
|||
void lock() override;
|
||||
void unlock() override;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_DRIVER_WEB_H
|
||||
|
|
|
@ -239,9 +239,6 @@ OS_Web::OS_Web() {
|
|||
godot_js_pwa_cb(&OS_Web::update_pwa_state_callback);
|
||||
|
||||
if (AudioDriverWeb::is_available()) {
|
||||
#ifdef NO_THREADS
|
||||
audio_drivers.push_back(memnew(AudioDriverScriptProcessor));
|
||||
#endif
|
||||
audio_drivers.push_back(memnew(AudioDriverWorklet));
|
||||
}
|
||||
for (int i = 0; i < audio_drivers.size(); i++) {
|
||||
|
|
|
@ -261,12 +261,7 @@ void NavigationRegion3D::bake_navigation_mesh(bool p_on_thread) {
|
|||
BakeThreadsArgs *args = memnew(BakeThreadsArgs);
|
||||
args->nav_region = this;
|
||||
|
||||
if (p_on_thread && !OS::get_singleton()->can_use_threads()) {
|
||||
WARN_PRINT("NavigationMesh bake 'on_thread' will be disabled as the current OS does not support multiple threads."
|
||||
"\nAs a fallback the navigation mesh will bake on the main thread which can cause framerate issues.");
|
||||
}
|
||||
|
||||
if (p_on_thread && OS::get_singleton()->can_use_threads()) {
|
||||
if (p_on_thread) {
|
||||
bake_thread.start(_bake_navigation_mesh, args);
|
||||
} else {
|
||||
_bake_navigation_mesh(args);
|
||||
|
|
|
@ -116,19 +116,11 @@ void AudioEffectRecordInstance::init() {
|
|||
recording_data.clear(); //Clear data completely and reset length
|
||||
is_recording = true;
|
||||
|
||||
#ifdef NO_THREADS
|
||||
AudioServer::get_singleton()->add_update_callback(&AudioEffectRecordInstance::_update, this);
|
||||
#else
|
||||
io_thread.start(_thread_callback, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioEffectRecordInstance::finish() {
|
||||
#ifdef NO_THREADS
|
||||
AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
|
||||
#else
|
||||
io_thread.wait_to_finish();
|
||||
#endif
|
||||
}
|
||||
|
||||
AudioEffectRecordInstance::~AudioEffectRecordInstance() {
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include "core/templates/command_queue_mt.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
#if !defined(NO_THREADS)
|
||||
|
||||
namespace TestCommandQueue {
|
||||
|
||||
class ThreadWork {
|
||||
|
@ -426,6 +424,4 @@ TEST_CASE("[Stress][CommandQueue] Stress test command queue") {
|
|||
}
|
||||
} // namespace TestCommandQueue
|
||||
|
||||
#endif // !defined(NO_THREADS)
|
||||
|
||||
#endif // TEST_COMMAND_QUEUE_H
|
||||
|
|
Loading…
Reference in New Issue