Skip to content

Commit

Permalink
Use std threads instead of godot's
Browse files Browse the repository at this point in the history
Don't really understand why, but waiting for a godot thread
to finish crashed this ,-,
  • Loading branch information
arlo-phoenix committed Dec 1, 2023
1 parent da95616 commit 120aae3
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 24 deletions.
15 changes: 8 additions & 7 deletions src/dbus_client_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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<DBusMessage> request_message = _client->create_request(_destination,
_path,
Expand All @@ -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);
}
Expand Down
6 changes: 4 additions & 2 deletions src/dbus_client_node.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once

#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/classes/thread.hpp>

#include <thread>

#include "dbus_client.h"
#include "dbus_level.h"
Expand All @@ -28,7 +29,8 @@ class DBusClientNode : public Node {
* @param callback
*/
void _request(const Ref<DBusMessage> &p_request, Callable callback);
Thread _thread;
std::thread _thread;
bool _thread_running = false;
bool _autostart = true;
bool _use_threads = false;

Expand Down
15 changes: 4 additions & 11 deletions src/dbus_server_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() :
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions src/dbus_server_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@
#include "dbus_method.h"
#include <godot_cpp/classes/mutex.hpp>
#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/classes/thread.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/templates/hash_map.hpp>

#include <mutex>
#include <thread>

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<String, Ref<DBusMethod>> _method_map;
Expand All @@ -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:
Expand Down

0 comments on commit 120aae3

Please sign in to comment.