From 120aae354391cc1094279a7c663dd85d4d1b07cf Mon Sep 17 00:00:00 2001 From: arlo-phoenix Date: Fri, 1 Dec 2023 11:39:51 +0100 Subject: [PATCH] Use std threads instead of godot's Don't really understand why, but waiting for a godot thread to finish crashed this ,-, --- src/dbus_client_node.cpp | 15 ++++++++------- src/dbus_client_node.h | 6 ++++-- src/dbus_server_node.cpp | 15 ++++----------- src/dbus_server_node.h | 9 +++++---- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/dbus_client_node.cpp b/src/dbus_client_node.cpp index 8a291b0..da55dfc 100644 --- a/src/dbus_client_node.cpp +++ b/src/dbus_client_node.cpp @@ -96,8 +96,8 @@ void DBusClientNode::open() { } void DBusClientNode::close() { - if (_thread.is_started()) { - _thread.wait_to_finish(); + if (_thread_running) { + _thread.join(); } _client->close(); @@ -156,9 +156,10 @@ Error DBusClientNode::request(const Variant **p_args, GDExtensionInt p_arg_count } const Callable callback = *p_args[1]; - if (_use_threads && _thread.is_alive()) { - _thread.wait_to_finish(); + if (_thread_running) { + _thread.join(); } + _thread_running = true; Ref request_message = _client->create_request(_destination, _path, @@ -170,9 +171,9 @@ Error DBusClientNode::request(const Variant **p_args, GDExtensionInt p_arg_count } if (_use_threads) { - Callable async_request = Callable(this, "_request"); - async_request = async_request.bind(request_message, callback); - _thread.start(async_request); + _thread = std::thread([this, request_message, callback]() { + _request(request_message, callback); + }); } else { _request(request_message, callback); } diff --git a/src/dbus_client_node.h b/src/dbus_client_node.h index 8ea3a79..229f8b3 100644 --- a/src/dbus_client_node.h +++ b/src/dbus_client_node.h @@ -1,7 +1,8 @@ #pragma once #include -#include + +#include #include "dbus_client.h" #include "dbus_level.h" @@ -28,7 +29,8 @@ class DBusClientNode : public Node { * @param callback */ void _request(const Ref &p_request, Callable callback); - Thread _thread; + std::thread _thread; + bool _thread_running = false; bool _autostart = true; bool _use_threads = false; diff --git a/src/dbus_server_node.cpp b/src/dbus_server_node.cpp index b3b4c81..73c0337 100644 --- a/src/dbus_server_node.cpp +++ b/src/dbus_server_node.cpp @@ -31,14 +31,13 @@ void DBusServerNode::_bind_methods() { ClassDB::bind_method(D_METHOD("stop"), &DBusServerNode::stop); ClassDB::bind_method(D_METHOD("_server_thread_loop"), &DBusServerNode::_server_thread_loop); - ClassDB::bind_method(D_METHOD("_process_bus"), &DBusServerNode::_process_bus); ADD_PROPERTY(PropertyInfo(Variant::STRING, "object_path"), "set_object_path", "get_object_path"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "interface_name"), "set_interface_name", "get_interface_name"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "methods", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "DBusMethod")), "set_methods", "get_methods"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autostart"), "set_autostart", "get_autostart"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_level", PROPERTY_HINT_ENUM, "USER, SYSTEM"), "set_bus_level", "get_bus_level"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "running", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_READ_ONLY), "", "is_running"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "running"), "", "is_running"); } DBusServerNode::DBusServerNode() : @@ -68,7 +67,7 @@ void DBusServerNode::_server_thread_loop() { const uint64_t BUS_WAIT_TIME = 50000; //0.5s while (is_running()) { //do processing on main thread, since need to wait for callback anyways and sometimes this outputs notifications which crashes outside of the main thread - r = call_deferred("_process_bus"); + r = sd_bus_process(_bus, NULL); ERR_BUS_FAIL("Failed to process bus"); if (r > 0) //if processed try to process another one without waiting @@ -87,10 +86,6 @@ void DBusServerNode::_server_thread_loop() { } } -int DBusServerNode::_process_bus() { - return sd_bus_process(_bus, NULL); -} - // Setter and Getter for _object_path void DBusServerNode::set_object_path(const String &p_name) { ERR_FAIL_COND(_running); @@ -185,16 +180,14 @@ void DBusServerNode::start() { r = sd_bus_request_name(_bus, _interface_name, 0); ERR_BUS_FAIL("Failed to acquire service name " + String(_interface_name)); - _thread.start(Callable(this, "_server_thread_loop")); + _thread = std::thread(&DBusServerNode::_server_thread_loop, this); _running = true; } void DBusServerNode::stop() { ERR_FAIL_COND_MSG(!_running, "Already stopped"); _set_running(false); - if (_thread.is_alive()) { - _thread.wait_to_finish(); - } + _thread.join(); sd_bus_slot_unref(_slot); sd_bus_unref(_bus); _slot = nullptr; diff --git a/src/dbus_server_node.h b/src/dbus_server_node.h index c68542d..7b2df20 100644 --- a/src/dbus_server_node.h +++ b/src/dbus_server_node.h @@ -4,24 +4,26 @@ #include "dbus_method.h" #include #include -#include #include #include +#include +#include + using namespace godot; class DBusServerNode : public Node { GDCLASS(DBusServerNode, Node); private: - Thread _thread; + std::thread _thread; CharString _object_path; CharString _interface_name; Array _methods; bool _autostart; DBusLevel::Level _bus_level = DBusLevel::USER; - Mutex _lock; + std::mutex _lock; bool _running; HashMap> _method_map; @@ -32,7 +34,6 @@ class DBusServerNode : public Node { int _v_table_size; void _server_thread_loop(); - int _process_bus(); void _set_running(const bool p_running); protected: