if (!addr) {
ERROR("failed");
} else {
- eldbusConnection = DBus::EldbusConnectionCallbackHandle{
- eldbus_address_connection_get(std::get<0>(addr).c_str()),
- eldbus_connection_unref };
+ eldbusConnection = std::make_shared<EldbusConnection>(
+ eldbus_address_connection_get(std::get<0>(addr).c_str()));
}
eventListener = atspi_event_listener_new(onAtspiEventCb, this, nullptr);
using CallType = void(std::string, std::string, VariantSetterType);
};
template <typename CallType, typename InterfaceType, typename ... ARGS> void callFunction(
- const EldbusConnectionCallbackHandle &eldbusConnection,
+ const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection,
const std::string &interface,
const std::shared_ptr<InterfaceType> &obj,
const std::string &funcName,
}
template <typename CallType, typename InterfaceType, typename ... ARGS> void callFunction(
- const EldbusConnectionCallbackHandle &eldbusConnection,
+ const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection,
const std::shared_ptr<InterfaceType> &obj,
const std::string &funcName,
typename FunctionCallbackType<CallType>::type callback,
}
template <typename CallType, typename InterfaceType, typename ... ARGS> void getProperty(
- const EldbusConnectionCallbackHandle &eldbusConnection,
+ const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection,
const std::string &interface,
const std::shared_ptr<InterfaceType> &obj,
const std::string &funcName,
}
template <typename CallType, typename InterfaceType, typename ... ARGS> void getProperty(
- const EldbusConnectionCallbackHandle &eldbusConnection,
+ const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection,
const std::shared_ptr<InterfaceType> &obj,
const std::string &funcName,
typename FunctionCallbackType<CallType>::type callback,
}
template <typename CallType, typename InterfaceType, typename Value> void setProperty(
- const EldbusConnectionCallbackHandle &eldbusConnection,
+ const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection,
const std::string &interface,
const std::shared_ptr<InterfaceType> &obj,
const std::string &func_name,
}
template <typename CallType, typename InterfaceType, typename A> void setProperty(
- const EldbusConnectionCallbackHandle &eldbusConnection,
+ const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection,
const std::shared_ptr<InterfaceType> &obj,
const std::string &func_name,
AsyncCallback<void> callback,
namespace
{
- void getValueTemplateFunction(const EldbusConnectionCallbackHandle &eldbusConnection, const AtspiValuePtr &valueInterface, const std::string paramName,
+ void getValueTemplateFunction(const std::shared_ptr<DBus::EldbusConnection> &eldbusConnection, const AtspiValuePtr &valueInterface, const std::string paramName,
AsyncCallback<double> callback)
{
getProperty<double()>(
bool setPropertyBool(const char *bus, const char *path, const char *interface, const char *property, Eina_Bool value);
- DBus::EldbusConnectionCallbackHandle eldbusConnection;
+ std::shared_ptr<DBus::EldbusConnection> eldbusConnection;
AtspiEventListener *eventListener;
std::vector<WatchCallback> watchedCallbacks;
void onAtspiEvent(AtspiEvent *event);
debugPrintFunc(buf.data(), buf.size());
}
-DBus::EldbusConnectionCallbackHandle DBus::getDBusConnectionByName(const std::string &name)
+std::shared_ptr<DBus::EldbusConnection> DBus::getDBusConnectionByName(const std::string &name)
{
eldbus_init();
auto z = getDBusConnectionByType(ConnectionType::SYSTEM);
auto connection = eldbus_address_connection_get(name.c_str());
- return { connection, [](Eldbus_Connection * c)
- {
- eldbus_connection_unref(c);
- eldbus_shutdown();
- } };
+ auto ptr = std::make_shared<EldbusConnection>(connection);
+ eldbus_shutdown();
+ return ptr;
}
-DBus::EldbusConnectionCallbackHandle DBus::getDBusConnectionByType(ConnectionType connectionType)
+std::shared_ptr<DBus::EldbusConnection> DBus::getDBusConnectionByType(ConnectionType connectionType)
{
Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
}
eldbus_init();
- return { eldbus_connection_get(eldbusType), [](Eldbus_Connection * c)
- {
- eldbus_connection_unref(c);
- eldbus_shutdown();
- } };
+ auto connection = eldbus_connection_get(eldbusType);
+ auto ptr = std::make_shared<EldbusConnection>(connection);
+ eldbus_shutdown();
+ return ptr;
}
DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::string interfaceName, ConnectionType tp) :
}
};
-DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::string interfaceName, const EldbusConnectionCallbackHandle &conn)
+DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::string interfaceName, const std::shared_ptr<DBus::EldbusConnection> &conn)
{
if (!conn)
connectionState.connection = getDBusConnectionByType(ConnectionType::SESSION);
std::ostringstream o;
o << "bus = " << busName << " path = " << pathName << " connection = " <<
- eldbus_connection_unique_name_get(connectionState.connection.get());
+ eldbus_connection_unique_name_get(connectionState.connection->get());
info = o.str();
auto c = connectionState.connection;
connectionState.object = {
- eldbus_object_get(connectionState.connection.get(), busName.c_str(), pathName.c_str()),
+ eldbus_object_get(connectionState.connection->get(), busName.c_str(), pathName.c_str()),
[c](Eldbus_Object * p)
{
eldbus_object_unref(p);
}
};
if (connectionState.object) {
- connectionState.proxy = eldbus_proxy_get(connectionState.object.get(), interfaceName.c_str());
+ connectionState.proxy = {
+ eldbus_proxy_get(connectionState.object.get(), interfaceName.c_str()),
+ [obj = connectionState.object](Eldbus_Proxy * p)
+ {
+ eldbus_proxy_unref(p);
+ }
+ };
if (interfaceName != DBUS_INTERFACE_PROPERTIES) {
- connectionState.propertiesProxy = eldbus_proxy_get(connectionState.object.get(), DBUS_INTERFACE_PROPERTIES);
+ connectionState.propertiesProxy = {
+ eldbus_proxy_get(connectionState.object.get(), DBUS_INTERFACE_PROPERTIES),
+ [obj = connectionState.object](Eldbus_Proxy * p)
+ {
+ eldbus_proxy_unref(p);
+ }
+ };
} else {
connectionState.propertiesProxy = connectionState.proxy;
}
{
}
-DBus::DBusServer::DBusServer(const EldbusConnectionCallbackHandle &conn)
+DBus::DBusServer::DBusServer(const std::shared_ptr<DBus::EldbusConnection> &conn)
{
if (!conn)
connection = getDBusConnectionByType(ConnectionType::SESSION);
std::unordered_map<std::string, DBus::DBusInterfaceDescription::PropertyInfo> propertiesMap;
std::unordered_map<unsigned int, DBus::DBusInterfaceDescription::SignalInfo> signalsMap;
- Eldbus_Connection *connection = nullptr;
+ std::shared_ptr<DBus::EldbusConnection> connection;
};
static std::unordered_map<const Eldbus_Service_Interface *, std::unique_ptr<Implementation>> globalEntries;
static std::mutex globalEntriesMutex;
static thread_local const char *currentObjectPath = "";
-static thread_local Eldbus_Connection *currentConnection = nullptr;
+static thread_local std::shared_ptr<DBus::EldbusConnection> currentConnection;
class CurrentObjectSetter
{
public:
- CurrentObjectSetter(Eldbus_Connection *con, const Eldbus_Message *m)
+ CurrentObjectSetter(std::shared_ptr<DBus::EldbusConnection> con, const Eldbus_Message *m)
{
currentObjectPath = eldbus_message_path_get(m);
- currentConnection = con;
+ currentConnection = std::move(con);
}
~CurrentObjectSetter()
{
currentObjectPath = "";
- currentConnection = nullptr;
+ currentConnection = {};
}
CurrentObjectSetter(const CurrentObjectSetter &) = delete;
CurrentObjectSetter(CurrentObjectSetter &&) = delete;
return currentObjectPath;
}
-DBus::EldbusConnectionCallbackHandle DBus::DBusServer::getCurrentConnection()
+std::shared_ptr<DBus::EldbusConnection> DBus::DBusServer::getCurrentConnection()
{
- auto c = currentConnection;
- return { eldbus_connection_ref(c), detail::caller_eldbus_connection_unref() };
+ return currentConnection;
}
static Eina_Bool property_get_callback(const Eldbus_Service_Interface *iface, const char *propertyName, Eldbus_Message_Iter *iter,
}
static void addInterfaceImpl(bool fallback, const std::string &pathName,
- const DBus::EldbusConnectionCallbackHandle &connection,
+ const std::shared_ptr<DBus::EldbusConnection> &connection,
const std::string &interfaceName,
std::unordered_map<unsigned int, std::pair<const Eldbus_Service_Interface *, unsigned int>> &signalData,
DBus::detail::StringStorage &strings,
std::move(methodsMap),
std::move(propertiesMap),
std::move(signalsMap),
- connection.get()
+ connection
});
{
std::lock_guard<std::mutex> lock(globalEntriesMutex);
auto v = fallback ?
- eldbus_service_interface_fallback_register(connection.get(), pathName.c_str(), &impl->dsc) :
- eldbus_service_interface_register(connection.get(), pathName.c_str(), &impl->dsc);
+ eldbus_service_interface_fallback_register(connection->get(), pathName.c_str(), &impl->dsc) :
+ eldbus_service_interface_register(connection->get(), pathName.c_str(), &impl->dsc);
ASSERT(v);
globalEntries[v] = std::move(impl);
DBUS_DEBUG("registering interface %p (%d)", v, fallback ? 1 : 0);
}
}
-DBus::EldbusConnectionCallbackHandle DBus::DBusServer::getConnection()
+std::shared_ptr<DBus::EldbusConnection> DBus::DBusServer::getConnection()
{
return connection;
}
return getConnectionName(connection);
}
-std::string DBus::getConnectionName(const EldbusConnectionCallbackHandle &c)
+std::string DBus::getConnectionName(const std::shared_ptr<DBus::EldbusConnection> &c)
{
- return eldbus_connection_unique_name_get(c.get());
+ return eldbus_connection_unique_name_get(c->get());
}
#include <type_traits>
#include <tuple>
#include <atomic>
+#include <thread>
#define DBUS_DEBUG(...) do { DBus::debugPrint(__FILE__, __LINE__, __VA_ARGS__); } while(0)
};
/// \cond
- using EldbusConnectionCallbackHandle = std::shared_ptr<Eldbus_Connection>;
+ class EldbusConnection
+ {
+ Eldbus_Connection *ptr = nullptr;
+ public:
+ EldbusConnection(Eldbus_Connection *c) : ptr(c)
+ {
+ eldbus_init();
+ }
+ EldbusConnection() = delete;
+ EldbusConnection(const EldbusConnection &) = delete;
+ EldbusConnection(EldbusConnection &&) = delete;
+ ~EldbusConnection()
+ {
+ eldbus_connection_unref(ptr);
+ eldbus_shutdown();
+ }
+
+ Eldbus_Connection *get() const
+ {
+ return ptr;
+ }
+ };
+ //using EldbusConnectionCallbackHandle = std::shared_ptr<Eldbus_Connection>;
using EldbusMessageCallbackHandle = std::unique_ptr<Eldbus_Message, detail::caller_eldbus_message_unref>;
using EldbusObjectCallbackHandle = std::shared_ptr<Eldbus_Object>;
+ using EldbusProxyHandle = std::shared_ptr<Eldbus_Proxy>;
/// \endcond
/**
constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
struct ConnectionState {
- EldbusConnectionCallbackHandle connection;
+ std::shared_ptr<DBus::EldbusConnection> connection;
EldbusObjectCallbackHandle object;
- Eldbus_Proxy *proxy = nullptr; // proxy lives only as long as object
- Eldbus_Proxy *propertiesProxy = nullptr;
+ EldbusProxyHandle proxy;
+ EldbusProxyHandle propertiesProxy;
};
+ using CallAsyncDataType = std::tuple<CallId, std::function<void(const Eldbus_Message *)>>;
+
static void callAsyncCb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
{
- auto d = (std::pair<CallId, std::function<void(const Eldbus_Message *)>> *)data;
- DBUS_DEBUG("call %d: got reply", d->first.id);
- d->second(msg);
+ auto d = (CallAsyncDataType *)data;
+ DBUS_DEBUG("call %d: got reply", std::get<0>(*d).id);
+ std::get<1>(*d)(msg);
}
static void pendingFreeCb(void *data, const void *)
{
- auto d = (std::pair<CallId, std::function<void(const Eldbus_Message *)>> *)data;
- DBUS_DEBUG("call %d: deleting", d->first.id);
+ auto d = (CallAsyncDataType *)data;
+ DBUS_DEBUG("call %d: deleting", std::get<0>(*d).id);
delete d;
}
template <typename RETTYPE, typename ... ARGS>
}
DBUS_DEBUG("call %d: calling '%s'", callId.id, funcName.c_str());
- EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new(proxy, funcName.c_str())};
+ EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new(proxy.get(), funcName.c_str())};
if (!msg) {
DBUS_DEBUG("call %d: failed", callId.id);
return Error { "failed to create message" };
}
detail::packValues(callId, msg.get(), args...);
- auto replyRawPtr = eldbus_proxy_send_and_block(proxy, msg.release(), ELDBUS_CALL_TIMEOUT);
+ auto replyRawPtr = eldbus_proxy_send_and_block(proxy.get(), msg.release(), ELDBUS_CALL_TIMEOUT);
EldbusMessageCallbackHandle reply{ replyRawPtr };
DBUS_DEBUG("call %d: calling '%s' done", callId.id, funcName.c_str());
if (!reply) {
}
template <typename RETTYPE, typename ... ARGS>
- void asyncCall(CallId callId, ConnectionState connectionState, bool property, const std::string &funcName,
+ void asyncCall(CallId callId, ConnectionState connectionState,
+ bool property, const std::string &funcName,
std::function<void(RETTYPE)> callback, const ARGS &... args)
{
auto proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
return;
}
- EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new(proxy, funcName.c_str())};
+ EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new(proxy.get(), funcName.c_str())};
if (!msg) {
DBUS_DEBUG("call %d: failed", callId.id);
callback(Error { "failed to create message" });
return;
}
- auto cbData = new std::pair<CallId, std::function<void(const Eldbus_Message *)>> {callId,
- [callback, connectionState, callId](const Eldbus_Message * reply)
+ auto cbData = new CallAsyncDataType{callId, [callback, callId, proxy ]
+ (const Eldbus_Message * reply)
{
DBUS_DEBUG("call %d: calling done", callId.id);
if (!reply) {
callback(detail::unpackValues<RETTYPE>(callId, reply));
}
}
- }
- };
+ } };
detail::packValues(callId, msg.get(), args...);
- auto pending = eldbus_proxy_send(proxy, msg.release(), callAsyncCb, cbData, ELDBUS_CALL_TIMEOUT);
+ auto pending = eldbus_proxy_send(proxy.get(), msg.release(), callAsyncCb, cbData, ELDBUS_CALL_TIMEOUT);
if (pending) {
eldbus_pending_free_cb_add(pending, pendingFreeCb, cbData);
DBUS_DEBUG("call %d: call sent", callId.id);
* @param conn connection object from getDBusConnectionByType call
*/
DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
- const EldbusConnectionCallbackHandle &conn = {});
+ const std::shared_ptr<DBus::EldbusConnection> &conn = {});
/**
* @brief Destructor object.
*
}
};
auto tmp = new std::function<void(const Eldbus_Message *msg)> { std::move(callbackLambda) };
- auto handler = eldbus_proxy_signal_handler_add(connectionState.proxy, signalName.c_str(), listenerCallback, tmp);
+ auto handler = eldbus_proxy_signal_handler_add(connectionState.proxy.get(), signalName.c_str(), listenerCallback, tmp);
destructors.push_back([ = ]() {
eldbus_signal_handler_del(handler);
delete tmp;
/**
* @brief Constructs dbus server on connection from getDBusConnectionByType
*/
- DBusServer(const EldbusConnectionCallbackHandle &conn);
+ DBusServer(const std::shared_ptr<DBus::EldbusConnection> &conn);
/**
* @brief Destructor
*
/**
* @brief Returns connection object for this dbus server object
*
- * @return EldbusConnectionCallbackHandle connection object
+ * @return connection object
*/
- EldbusConnectionCallbackHandle getConnection();
+ std::shared_ptr<DBus::EldbusConnection> getConnection();
/**
* @brief Emits signal
* };
* \endcode
*/
- static EldbusConnectionCallbackHandle getCurrentConnection();
+ static std::shared_ptr<DBus::EldbusConnection> getCurrentConnection();
private:
/// \cond
- EldbusConnectionCallbackHandle connection;
+ std::shared_ptr<DBus::EldbusConnection> connection;
std::vector<std::function<void()>> destructors;
std::unordered_map<unsigned int, std::pair<const Eldbus_Service_Interface *, unsigned int>> signalData;
/// \endcond
callState->reply = eldbus_message_error_new(callState->message.get(), "org.freedesktop.DBus.Error.Failed", v.getError().message.c_str());
}
if (!callState->replyRunning) {
- eldbus_connection_send(connection.get(), callState->reply, NULL, NULL, -1);
+ eldbus_connection_send(connection->get(), callState->reply, NULL, NULL, -1);
}
};
Eldbus_Message *ret = nullptr;
}
/// \cond
- EldbusConnectionCallbackHandle getDBusConnectionByType(ConnectionType tp);
- EldbusConnectionCallbackHandle getDBusConnectionByName(const std::string &name);
- std::string getConnectionName(const EldbusConnectionCallbackHandle &);
+ std::shared_ptr<EldbusConnection> getDBusConnectionByType(ConnectionType tp);
+ std::shared_ptr<EldbusConnection> getDBusConnectionByName(const std::string &name);
+ std::string getConnectionName(const std::shared_ptr<EldbusConnection> &);
/// \endcond
}
add(desc, "removeSwitchConfigurationItem", &DBusInterfaceImpl::removeSwitchConfigurationItem);
dbusServer.addInterface(PATH, desc);
- eldbus_name_request(dbusServer.getConnection().get(), BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, onNameRequest, nullptr);
+ eldbus_name_request(dbusServer.getConnection()->get(), BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, onNameRequest, nullptr);
}
private:
DBus::DBusServer dbusServer;
#include <glib.h>
#include <glib-object.h>
-#include <Eldbus.h>
#include <tuple>
#include <memory>
#include <functional>
initializeServices(char *busNameDest, size_t busNameSize)
{
auto connection = DBus::getDBusConnectionByType(DBus::ConnectionType::SYSTEM);
- std::string busName = eldbus_connection_unique_name_get(connection.get());
+ std::string busName = eldbus_connection_unique_name_get(connection->get());
assert(busName.size() + 2 < busNameSize);
strncpy(busNameDest + 1, busName.c_str(), busName.size());
busNameDest[0] = 1;