forked from Kistler-Group/sdbus-cpp
This reorganizes the layers of abstraction in the sense how `Message` depends on `Connection` and vice versa. Now, `Message` has a link to the `Connection`. This replaces the shortcut link to the low-level `SdBus` interface that the `Message` kept. The interactions from `Message` now go through `Connection` which forwards them to `SdBus`. `Connection` is now a sole owner of the low-level `SdBus` interface. This allows for future changes around `SdBus` (e.g. a change from virtual functions back to non-virtual functions) without affecting the rest of the library. `Proxy`s and `Object`s can now send messages directly without having to go through `Connection`. The `Connection` no more depends on `Message` business-logic methods; it serves only as a factory for messages. The flow for creating messages: `Proxy`/`Object` -> `Connection` -> `SdBus` The flow for sending messages: (`Proxy`/`Object` ->) `Message` -> `Connection` -> `SdBus` This also better reflects how dependencies are managed in the underlying sd-bus library. Additionally, `getSdBusInterface()` methods are removed which was anyway planned, and improves the design by "Tell, don't ask" principle. This refactoring is the necessary enabler for other upcoming improvements (regarding sending long messages, or creds refactoring, for example).
148 lines
5.7 KiB
C++
148 lines
5.7 KiB
C++
/**
|
|
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
|
* (C) 2016 - 2024 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
|
*
|
|
* @file Proxy.h
|
|
*
|
|
* Created on: Nov 8, 2016
|
|
* Project: sdbus-c++
|
|
* Description: High-level D-Bus IPC C++ library based on sd-bus
|
|
*
|
|
* This file is part of sdbus-c++.
|
|
*
|
|
* sdbus-c++ is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* sdbus-c++ is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef SDBUS_CXX_INTERNAL_PROXY_H_
|
|
#define SDBUS_CXX_INTERNAL_PROXY_H_
|
|
|
|
#include "sdbus-c++/IProxy.h"
|
|
|
|
#include "IConnection.h"
|
|
#include "sdbus-c++/Types.h"
|
|
|
|
#include <deque>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include SDBUS_HEADER
|
|
#include <vector>
|
|
|
|
namespace sdbus::internal {
|
|
|
|
class Proxy
|
|
: public IProxy
|
|
{
|
|
public:
|
|
Proxy( sdbus::internal::IConnection& connection
|
|
, ServiceName destination
|
|
, ObjectPath objectPath );
|
|
Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
|
|
, ServiceName destination
|
|
, ObjectPath objectPath );
|
|
Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
|
|
, ServiceName destination
|
|
, ObjectPath objectPath
|
|
, dont_run_event_loop_thread_t );
|
|
|
|
MethodCall createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName) const override;
|
|
MethodCall createMethodCall(const char* interfaceName, const char* methodName) const override;
|
|
MethodReply callMethod(const MethodCall& message) override;
|
|
MethodReply callMethod(const MethodCall& message, uint64_t timeout) override;
|
|
PendingAsyncCall callMethodAsync(const MethodCall& message, async_reply_handler asyncReplyCallback) override;
|
|
Slot callMethodAsync( const MethodCall& message
|
|
, async_reply_handler asyncReplyCallback
|
|
, return_slot_t ) override;
|
|
PendingAsyncCall callMethodAsync( const MethodCall& message
|
|
, async_reply_handler asyncReplyCallback
|
|
, uint64_t timeout ) override;
|
|
Slot callMethodAsync( const MethodCall& message
|
|
, async_reply_handler asyncReplyCallback
|
|
, uint64_t timeout
|
|
, return_slot_t ) override;
|
|
std::future<MethodReply> callMethodAsync(const MethodCall& message, with_future_t) override;
|
|
std::future<MethodReply> callMethodAsync(const MethodCall& message, uint64_t timeout, with_future_t) override;
|
|
|
|
void registerSignalHandler( const InterfaceName& interfaceName
|
|
, const SignalName& signalName
|
|
, signal_handler signalHandler ) override;
|
|
void registerSignalHandler( const char* interfaceName
|
|
, const char* signalName
|
|
, signal_handler signalHandler ) override;
|
|
Slot registerSignalHandler( const InterfaceName& interfaceName
|
|
, const SignalName& signalName
|
|
, signal_handler signalHandler
|
|
, return_slot_t ) override;
|
|
Slot registerSignalHandler( const char* interfaceName
|
|
, const char* signalName
|
|
, signal_handler signalHandler
|
|
, return_slot_t ) override;
|
|
void unregister() override;
|
|
|
|
[[nodiscard]] sdbus::IConnection& getConnection() const override;
|
|
[[nodiscard]] const ObjectPath& getObjectPath() const override;
|
|
[[nodiscard]] Message getCurrentlyProcessedMessage() const override;
|
|
|
|
private:
|
|
static int sdbus_signal_handler(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError);
|
|
static int sdbus_async_reply_handler(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError);
|
|
|
|
private:
|
|
friend PendingAsyncCall;
|
|
|
|
std::unique_ptr< sdbus::internal::IConnection
|
|
, std::function<void(sdbus::internal::IConnection*)>
|
|
> connection_;
|
|
ServiceName destination_;
|
|
ObjectPath objectPath_;
|
|
|
|
std::vector<Slot> floatingSignalSlots_;
|
|
|
|
struct SignalInfo
|
|
{
|
|
signal_handler callback;
|
|
Proxy& proxy;
|
|
Slot slot;
|
|
};
|
|
|
|
struct AsyncCallInfo
|
|
{
|
|
async_reply_handler callback;
|
|
Proxy& proxy;
|
|
Slot slot{};
|
|
bool finished{false};
|
|
bool floating;
|
|
};
|
|
|
|
// Container keeping track of pending async calls
|
|
class FloatingAsyncCallSlots
|
|
{
|
|
public:
|
|
~FloatingAsyncCallSlots();
|
|
void push_back(std::shared_ptr<AsyncCallInfo> asyncCallInfo);
|
|
void erase(AsyncCallInfo* info);
|
|
void clear();
|
|
|
|
private:
|
|
std::mutex mutex_;
|
|
std::deque<std::shared_ptr<AsyncCallInfo>> slots_;
|
|
};
|
|
|
|
FloatingAsyncCallSlots floatingAsyncCallSlots_;
|
|
};
|
|
|
|
}
|
|
|
|
#endif /* SDBUS_CXX_INTERNAL_PROXY_H_ */
|