mirror of
https://github.com/Kistler-Group/sdbus-cpp.git
synced 2025-08-01 11:04:27 +02:00
WIP
This commit is contained in:
@@ -13,7 +13,9 @@ include(GNUInstallDirs) # Installation directories for `install` command and pkg
|
||||
#-------------------------------
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SYSTEMD REQUIRED libsystemd>=236)
|
||||
#pkg_check_modules(SYSTEMD REQUIRED libsystemd>=236)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-O0 -g")
|
||||
|
||||
#-------------------------------
|
||||
# SOURCE FILES CONFIGURATION
|
||||
@@ -80,7 +82,7 @@ set(SDBUSCPP_VERSION "${PROJECT_VERSION}")
|
||||
# We are building in two steps: first objects, then link them into a library,
|
||||
# and that's because we need object files since unit tests link against them.
|
||||
add_library(sdbuscppobjects OBJECT ${SDBUSCPP_SRCS})
|
||||
target_include_directories(sdbuscppobjects PUBLIC ${SYSTEMD_INCLUDE_DIRS})
|
||||
#target_include_directories(sdbuscppobjects PUBLIC ${SYSTEMD_INCLUDE_DIRS})
|
||||
target_compile_definitions(sdbuscppobjects PRIVATE BUILDLIB=1)
|
||||
set_target_properties(sdbuscppobjects PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -91,7 +93,7 @@ set_target_properties(sdbus-c++
|
||||
VERSION "${SDBUSCPP_VERSION}"
|
||||
SOVERSION "${SDBUSCPP_VERSION_MAJOR}"
|
||||
OUTPUT_NAME "sdbus-c++")
|
||||
target_link_libraries(sdbus-c++ ${SYSTEMD_LIBRARIES})
|
||||
target_link_libraries(sdbus-c++ -L/home/aeywalee/data/repos/systemd/.libs/ -lsystemd)
|
||||
|
||||
#----------------------------------
|
||||
# INSTALLATION
|
||||
|
@@ -79,7 +79,7 @@ void Connection::enterProcessingLoop()
|
||||
if (!success)
|
||||
break; // Exit processing loop
|
||||
if (success.asyncMsgsToProcess)
|
||||
processAsynchronousMessages();
|
||||
processUserRequests();
|
||||
}
|
||||
|
||||
loopThreadId_ = std::thread::id{};
|
||||
@@ -122,10 +122,10 @@ void Connection::removeObjectVTable(void* vtableHandle)
|
||||
sd_bus_slot_unref((sd_bus_slot *)vtableHandle);
|
||||
}
|
||||
|
||||
sdbus::MethodCall Connection::createMethodCall( const std::string& destination
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& methodName ) const
|
||||
MethodCall Connection::createMethodCall( const std::string& destination
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& methodName ) const
|
||||
{
|
||||
sd_bus_message *sdbusMsg{};
|
||||
|
||||
@@ -145,44 +145,9 @@ sdbus::MethodCall Connection::createMethodCall( const std::string& destination
|
||||
return MethodCall(sdbusMsg);
|
||||
}
|
||||
|
||||
sdbus::MethodReply Connection::callMethod(const MethodCall& message)
|
||||
{
|
||||
std::thread::id loopThreadId = loopThreadId_;
|
||||
|
||||
// Is the loop not yet on? => Go make synchronous call
|
||||
while (loopThreadId == std::thread::id{})
|
||||
{
|
||||
// Did the loop begin in the meantime? Or try_lock() failed spuriously?
|
||||
if (!loopMutex_.try_lock())
|
||||
continue;
|
||||
|
||||
// Synchronous call
|
||||
std::lock_guard<std::mutex> guard(loopMutex_, std::adopt_lock);
|
||||
return message.send();
|
||||
}
|
||||
|
||||
// Is the loop on and we are in the same thread? => Go for synchronous call
|
||||
if (loopThreadId == std::this_thread::get_id())
|
||||
{
|
||||
assert(!loopMutex_.try_lock());
|
||||
return message.send(); // Synchronous call
|
||||
}
|
||||
|
||||
// We are in a different thread than the loop thread => Asynchronous call
|
||||
UserRequest request{message, Message::Type::METHOD_CALL, {}, Message::Type::METHOD_REPLY};
|
||||
auto future = request.ret.get_future();
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(userRequestsMutex_);
|
||||
userRequests_.push(request);
|
||||
}
|
||||
// Wait for the reply from the loop thread
|
||||
auto reply = future.get();
|
||||
return *static_cast<const MethodReply*>(&reply);
|
||||
}
|
||||
|
||||
sdbus::Signal Connection::createSignal( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName ) const
|
||||
Signal Connection::createSignal( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName ) const
|
||||
{
|
||||
sd_bus_message *sdbusSignal{};
|
||||
|
||||
@@ -207,14 +172,61 @@ void* Connection::registerSignalHandler( const std::string& objectPath
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData )
|
||||
{
|
||||
sd_bus_slot *slot{};
|
||||
auto registerSignalHandler = [this]( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData )
|
||||
{
|
||||
sd_bus_slot *slot{};
|
||||
|
||||
auto filter = composeSignalMatchFilter(objectPath, interfaceName, signalName);
|
||||
auto r = sd_bus_add_match(bus_.get(), &slot, filter.c_str(), callback, userData);
|
||||
auto filter = composeSignalMatchFilter(objectPath, interfaceName, signalName);
|
||||
auto r = sd_bus_add_match(bus_.get(), &slot, filter.c_str(), callback, userData);
|
||||
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to register signal handler", -r);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to register signal handler", -r);
|
||||
|
||||
return slot;
|
||||
return slot;
|
||||
};
|
||||
|
||||
std::thread::id loopThreadId = loopThreadId_;
|
||||
|
||||
// Is the loop not yet on? => Go make synchronous call
|
||||
while (loopThreadId == std::thread::id{})
|
||||
{
|
||||
// Did the loop begin in the meantime? Or try_lock() failed spuriously?
|
||||
if (!loopMutex_.try_lock())
|
||||
continue;
|
||||
|
||||
// Synchronous call
|
||||
std::lock_guard<std::mutex> guard(loopMutex_, std::adopt_lock);
|
||||
return registerSignalHandler(objectPath, interfaceName, signalName, callback, userData);
|
||||
}
|
||||
|
||||
// Is the loop on and we are in the same thread? => Go for synchronous call
|
||||
if (loopThreadId == std::this_thread::get_id())
|
||||
{
|
||||
assert(!loopMutex_.try_lock());
|
||||
return registerSignalHandler(objectPath, interfaceName, signalName, callback, userData);
|
||||
}
|
||||
|
||||
// We are in a different thread than the loop thread => Asynchronous call
|
||||
std::promise<void*> result;
|
||||
auto future = result.get_future();
|
||||
queueUserRequest([registerSignalHandler, objectPath, interfaceName, signalName, callback, userData, &result]()
|
||||
{
|
||||
SCOPE_EXIT_NAMED(onSdbusError){ result.set_exception(std::current_exception()); };
|
||||
|
||||
void* slot = registerSignalHandler(objectPath, interfaceName, signalName, callback, userData);
|
||||
result.set_value(slot);
|
||||
|
||||
onSdbusError.dismiss();
|
||||
});
|
||||
auto request = std::make_unique<SignalRegistrationRequest>();
|
||||
request->registerSignalHandler = registerSignalHandler;
|
||||
auto future = request->result.get_future();
|
||||
queueUserRequest(std::move(request));
|
||||
// Wait for the reply from the loop thread
|
||||
return future.get();
|
||||
}
|
||||
|
||||
void Connection::unregisterSignalHandler(void* handlerCookie)
|
||||
@@ -222,11 +234,129 @@ void Connection::unregisterSignalHandler(void* handlerCookie)
|
||||
sd_bus_slot_unref((sd_bus_slot *)handlerCookie);
|
||||
}
|
||||
|
||||
void Connection::sendReplyAsynchronously(const sdbus::MethodReply& reply)
|
||||
//class AsyncExecutor
|
||||
//ifPossibleExecuteSync()
|
||||
|
||||
MethodReply Connection::callMethod(const MethodCall& message)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
asyncReplies_.push(reply);
|
||||
notifyProcessingLoop();
|
||||
//ifPossibleExecuteSync().otherwiseExecuteAsync();
|
||||
std::thread::id loopThreadId = loopThreadId_;
|
||||
|
||||
// Is the loop not yet on? => Go make synchronous call
|
||||
while (loopThreadId == std::thread::id{})
|
||||
{
|
||||
// Did the loop begin in the meantime? Or try_lock() failed spuriously?
|
||||
if (!loopMutex_.try_lock())
|
||||
continue;
|
||||
|
||||
// Synchronous call
|
||||
std::lock_guard<std::mutex> guard(loopMutex_, std::adopt_lock);
|
||||
return message.send();
|
||||
}
|
||||
|
||||
// Is the loop on and we are in the same thread? => Go for synchronous call
|
||||
if (loopThreadId == std::this_thread::get_id())
|
||||
{
|
||||
assert(!loopMutex_.try_lock());
|
||||
return message.send(); // Synchronous call
|
||||
}
|
||||
|
||||
// We are in a different thread than the loop thread => Asynchronous call
|
||||
auto request = std::make_unique<MethodCallRequest>();
|
||||
request->msg = message;
|
||||
auto future = request->result.get_future();
|
||||
queueUserRequest(std::move(request));
|
||||
// Wait for the reply from the loop thread
|
||||
return future.get();
|
||||
}
|
||||
|
||||
void Connection::callMethod(const AsyncMethodCall& message, void* callback, void* userData)
|
||||
{
|
||||
std::thread::id loopThreadId = loopThreadId_;
|
||||
|
||||
// Is the loop not yet on? => Go make synchronous call
|
||||
while (loopThreadId == std::thread::id{})
|
||||
{
|
||||
// Did the loop begin in the meantime? Or try_lock() failed spuriously?
|
||||
if (!loopMutex_.try_lock())
|
||||
continue;
|
||||
|
||||
// Synchronous call
|
||||
std::lock_guard<std::mutex> guard(loopMutex_, std::adopt_lock);
|
||||
return message.send(callback, userData);
|
||||
}
|
||||
|
||||
// Is the loop on and we are in the same thread? => Go for synchronous call
|
||||
if (loopThreadId == std::this_thread::get_id())
|
||||
{
|
||||
assert(!loopMutex_.try_lock());
|
||||
return message.send(callback, userData); // Synchronous call
|
||||
}
|
||||
|
||||
// We are in a different thread than the loop thread => Asynchronous call
|
||||
auto request = std::make_unique<AsyncMethodCallRequest>();
|
||||
request->msg = message;
|
||||
request->callback = callback;
|
||||
request->userData = userData;
|
||||
queueUserRequest(std::move(request));
|
||||
}
|
||||
|
||||
void Connection::sendMethodReply(const MethodReply& message)
|
||||
{
|
||||
std::thread::id loopThreadId = loopThreadId_;
|
||||
|
||||
// Is the loop not yet on? => Go make synchronous call
|
||||
while (loopThreadId == std::thread::id{})
|
||||
{
|
||||
// Did the loop begin in the meantime? Or try_lock() failed spuriously?
|
||||
if (!loopMutex_.try_lock())
|
||||
continue;
|
||||
|
||||
// Synchronous call
|
||||
std::lock_guard<std::mutex> guard(loopMutex_, std::adopt_lock);
|
||||
return message.send();
|
||||
}
|
||||
|
||||
// Is the loop on and we are in the same thread? => Go for synchronous call
|
||||
if (loopThreadId == std::this_thread::get_id())
|
||||
{
|
||||
assert(!loopMutex_.try_lock());
|
||||
return message.send(); // Synchronous call
|
||||
}
|
||||
|
||||
// We are in a different thread than the loop thread => Asynchronous call
|
||||
auto request = std::make_unique<MethodReplyRequest>();
|
||||
request->msg = message;
|
||||
queueUserRequest(std::move(request));
|
||||
}
|
||||
|
||||
void Connection::emitSignal(const Signal& message)
|
||||
{
|
||||
std::thread::id loopThreadId = loopThreadId_;
|
||||
|
||||
// Is the loop not yet on? => Go make synchronous call
|
||||
while (loopThreadId == std::thread::id{})
|
||||
{
|
||||
// Did the loop begin in the meantime? Or try_lock() failed spuriously?
|
||||
if (!loopMutex_.try_lock())
|
||||
continue;
|
||||
|
||||
// Synchronous call
|
||||
std::lock_guard<std::mutex> guard(loopMutex_, std::adopt_lock);
|
||||
return message.send();
|
||||
}
|
||||
|
||||
// Is the loop on and we are in the same thread? => Go for synchronous call
|
||||
if (loopThreadId == std::this_thread::get_id())
|
||||
{
|
||||
assert(!loopMutex_.try_lock());
|
||||
return message.send(); // Synchronous call
|
||||
}
|
||||
|
||||
// We are in a different thread than the loop thread => Asynchronous call
|
||||
auto request = std::make_unique<SignalEmissionRequest>();
|
||||
request->msg = message;
|
||||
queueUserRequest(std::move(request));
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::internal::IConnection> Connection::clone() const
|
||||
@@ -315,14 +445,23 @@ bool Connection::processPendingRequest()
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
void Connection::processAsynchronousMessages()
|
||||
void Connection::queueUserRequest(std::unique_ptr<IUserRequest>&& request)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
while (!asyncReplies_.empty())
|
||||
{
|
||||
auto reply = asyncReplies_.front();
|
||||
asyncReplies_.pop();
|
||||
reply.send();
|
||||
std::lock_guard<std::mutex> guard(userRequestsMutex_);
|
||||
userRequests_.push(std::move(request));
|
||||
}
|
||||
notifyProcessingLoop();
|
||||
}
|
||||
|
||||
void Connection::processUserRequests()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(userRequestsMutex_);
|
||||
while (!userRequests_.empty())
|
||||
{
|
||||
auto& reply = userRequests_.front();
|
||||
reply->process();
|
||||
userRequests_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
134
src/Connection.h
134
src/Connection.h
@@ -29,6 +29,7 @@
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <sdbus-c++/Message.h>
|
||||
#include "IConnection.h"
|
||||
#include "ScopeGuard.h"
|
||||
#include <systemd/sd-bus.h>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
@@ -51,7 +52,7 @@ namespace sdbus { namespace internal {
|
||||
};
|
||||
|
||||
Connection(BusType type);
|
||||
~Connection();
|
||||
~Connection() override;
|
||||
|
||||
void requestName(const std::string& name) override;
|
||||
void releaseName(const std::string& name) override;
|
||||
@@ -65,13 +66,13 @@ namespace sdbus { namespace internal {
|
||||
, void* userData ) override;
|
||||
void removeObjectVTable(void* vtableHandle) override;
|
||||
|
||||
sdbus::MethodCall createMethodCall( const std::string& destination
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& methodName ) const override;
|
||||
sdbus::Signal createSignal( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName ) const override;
|
||||
MethodCall createMethodCall( const std::string& destination
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& methodName ) const override;
|
||||
Signal createSignal( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName ) const override;
|
||||
|
||||
void* registerSignalHandler( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
@@ -80,8 +81,10 @@ namespace sdbus { namespace internal {
|
||||
, void* userData ) override;
|
||||
void unregisterSignalHandler(void* handlerCookie) override;
|
||||
|
||||
MethodReply callMethod(const MethodCall& message);
|
||||
void sendReplyAsynchronously(const sdbus::MethodReply& reply) override;
|
||||
MethodReply callMethod(const MethodCall& message) override;
|
||||
void callMethod(const AsyncMethodCall& message, void* callback, void* userData) override;
|
||||
void sendMethodReply(const MethodReply& message) override;
|
||||
void emitSignal(const Signal& message) override;
|
||||
|
||||
std::unique_ptr<sdbus::internal::IConnection> clone() const override;
|
||||
|
||||
@@ -95,12 +98,106 @@ namespace sdbus { namespace internal {
|
||||
return msgsToProcess || asyncMsgsToProcess;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO move down
|
||||
struct IUserRequest
|
||||
{
|
||||
virtual void process() = 0;
|
||||
virtual ~IUserRequest() = default;
|
||||
};
|
||||
|
||||
struct MethodCallRequest : IUserRequest
|
||||
{
|
||||
MethodCall msg;
|
||||
std::promise<MethodReply> result;
|
||||
|
||||
void process() override
|
||||
{
|
||||
SCOPE_EXIT_NAMED(onSdbusError){ result.set_exception(std::current_exception()); };
|
||||
|
||||
auto reply = msg.send();
|
||||
result.set_value(std::move(reply));
|
||||
|
||||
onSdbusError.dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
struct AsyncMethodCallRequest : IUserRequest
|
||||
{
|
||||
AsyncMethodCall msg;
|
||||
void* callback;
|
||||
void* userData;
|
||||
|
||||
// TODO: Catch exception and store to promise?
|
||||
void process() override
|
||||
{
|
||||
msg.send(callback, userData);
|
||||
}
|
||||
};
|
||||
|
||||
struct MethodReplyRequest : IUserRequest
|
||||
{
|
||||
MethodReply msg;
|
||||
|
||||
// TODO: Catch exception and store to promise?
|
||||
void process() override
|
||||
{
|
||||
msg.send();
|
||||
}
|
||||
};
|
||||
|
||||
struct SignalEmissionRequest : IUserRequest
|
||||
{
|
||||
Signal msg;
|
||||
|
||||
// TODO: Catch exception and store to promise?
|
||||
void process() override
|
||||
{
|
||||
msg.send();
|
||||
}
|
||||
};
|
||||
|
||||
struct SignalRegistrationRequest : IUserRequest
|
||||
{
|
||||
std::function<void*()> registerSignalHandler;
|
||||
std::promise<void*> result;
|
||||
|
||||
void process() override
|
||||
{
|
||||
SCOPE_EXIT_NAMED(onSdbusError){ result.set_exception(std::current_exception()); };
|
||||
|
||||
assert(registerSignalHandler);
|
||||
void* slot = registerSignalHandler();
|
||||
result.set_value(slot);
|
||||
|
||||
onSdbusError.dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
struct SignalUnregistrationRequest : IUserRequest
|
||||
{
|
||||
std::function<void()> unregisterSignalHandler;
|
||||
std::promise<void> result;
|
||||
|
||||
void process() override
|
||||
{
|
||||
SCOPE_EXIT_NAMED(onSdbusError){ result.set_exception(std::current_exception()); };
|
||||
|
||||
assert(unregisterSignalHandler);
|
||||
unregisterSignalHandler();
|
||||
result.set_value();
|
||||
|
||||
onSdbusError.dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
static sd_bus* openBus(Connection::BusType type);
|
||||
static void finishHandshake(sd_bus* bus);
|
||||
static int createLoopNotificationDescriptor();
|
||||
static void closeLoopNotificationDescriptor(int fd);
|
||||
bool processPendingRequest();
|
||||
void processAsynchronousMessages();
|
||||
void queueUserRequest(std::unique_ptr<IUserRequest>&& request);
|
||||
void processUserRequests();
|
||||
WaitResult waitForNextRequest();
|
||||
static std::string composeSignalMatchFilter( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
@@ -115,20 +212,7 @@ namespace sdbus { namespace internal {
|
||||
std::atomic<std::thread::id> loopThreadId_;
|
||||
std::mutex loopMutex_;
|
||||
|
||||
//std::queue<MethodReply> asyncReplies_;
|
||||
struct UserRequest
|
||||
{
|
||||
Message msg;
|
||||
Message::Type msgType;
|
||||
std::promise<Message> ret;
|
||||
Message::Type retType;
|
||||
|
||||
static_assert(sizeof(Message) == sizeof(MethodCall));
|
||||
static_assert(sizeof(Message) == sizeof(AsyncMethodCall));
|
||||
static_assert(sizeof(Message) == sizeof(MethodReply));
|
||||
static_assert(sizeof(Message) == sizeof(Signal));
|
||||
};
|
||||
std::queue<UserRequest> userRequests_;
|
||||
std::queue<std::unique_ptr<IUserRequest>> userRequests_;
|
||||
std::mutex userRequestsMutex_;
|
||||
|
||||
std::atomic<bool> exitLoopThread_;
|
||||
|
@@ -33,6 +33,7 @@
|
||||
// Forward declaration
|
||||
namespace sdbus {
|
||||
class MethodCall;
|
||||
class AsyncMethodCall;
|
||||
class MethodReply;
|
||||
class Signal;
|
||||
}
|
||||
@@ -49,14 +50,14 @@ namespace internal {
|
||||
, void* userData ) = 0;
|
||||
virtual void removeObjectVTable(void* vtableHandle) = 0;
|
||||
|
||||
virtual sdbus::MethodCall createMethodCall( const std::string& destination
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& methodName ) const = 0;
|
||||
virtual MethodCall createMethodCall( const std::string& destination
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& methodName ) const = 0;
|
||||
|
||||
virtual sdbus::Signal createSignal( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName ) const = 0;
|
||||
virtual Signal createSignal( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName ) const = 0;
|
||||
|
||||
virtual void* registerSignalHandler( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
@@ -68,7 +69,10 @@ namespace internal {
|
||||
virtual void enterProcessingLoopAsync() = 0;
|
||||
virtual void leaveProcessingLoop() = 0;
|
||||
|
||||
virtual void sendReplyAsynchronously(const sdbus::MethodReply& reply) = 0;
|
||||
virtual MethodReply callMethod(const MethodCall& message) = 0;
|
||||
virtual void callMethod(const AsyncMethodCall& message, void* callback, void* userData) = 0;
|
||||
virtual void sendMethodReply(const MethodReply& message) = 0;
|
||||
virtual void emitSignal(const Signal& message) = 0;
|
||||
|
||||
virtual std::unique_ptr<sdbus::internal::IConnection> clone() const = 0;
|
||||
|
||||
|
@@ -37,7 +37,7 @@ MethodResult::MethodResult(const MethodCall& msg, sdbus::internal::Object& objec
|
||||
void MethodResult::send(const MethodReply& reply) const
|
||||
{
|
||||
assert(object_ != nullptr);
|
||||
object_->sendReplyAsynchronously(reply);
|
||||
object_->sendMethodReply(reply);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -156,15 +156,12 @@ sdbus::Signal Object::createSignal(const std::string& interfaceName, const std::
|
||||
|
||||
void Object::emitSignal(const sdbus::Signal& message)
|
||||
{
|
||||
// TODO: Make signal emitting asynchronous. Now signal can probably be emitted only from user code
|
||||
// handled within the D-Bus processing loop thread, but not from any thread. In principle it will
|
||||
// be the same as async replies.
|
||||
message.send();
|
||||
connection_.emitSignal(message);
|
||||
}
|
||||
|
||||
void Object::sendReplyAsynchronously(const MethodReply& reply)
|
||||
void Object::sendMethodReply(const MethodReply& reply)
|
||||
{
|
||||
connection_.sendReplyAsynchronously(reply);
|
||||
connection_.sendMethodReply(reply);
|
||||
}
|
||||
|
||||
const std::vector<sd_bus_vtable>& Object::createInterfaceVTable(InterfaceData& interfaceData)
|
||||
|
@@ -84,7 +84,7 @@ namespace internal {
|
||||
sdbus::Signal createSignal(const std::string& interfaceName, const std::string& signalName) override;
|
||||
void emitSignal(const sdbus::Signal& message) override;
|
||||
|
||||
void sendReplyAsynchronously(const MethodReply& reply);
|
||||
void sendMethodReply(const MethodReply& reply);
|
||||
|
||||
private:
|
||||
using InterfaceName = std::string;
|
||||
|
@@ -49,7 +49,7 @@ ObjectProxy::ObjectProxy( std::unique_ptr<sdbus::internal::IConnection>&& connec
|
||||
{
|
||||
// The connection is ours only, so we have to manage event loop upon this connection,
|
||||
// so we get signals, async replies, and other messages from D-Bus.
|
||||
connection_->enterProcessingLoopAsync();
|
||||
// TODO uncomment connection_->enterProcessingLoopAsync();
|
||||
}
|
||||
|
||||
MethodCall ObjectProxy::createMethodCall(const std::string& interfaceName, const std::string& methodName)
|
||||
@@ -64,13 +64,16 @@ AsyncMethodCall ObjectProxy::createAsyncMethodCall(const std::string& interfaceN
|
||||
|
||||
MethodReply ObjectProxy::callMethod(const MethodCall& message)
|
||||
{
|
||||
return message.send();
|
||||
return connection_->callMethod(message);
|
||||
}
|
||||
|
||||
void ObjectProxy::callMethod(const AsyncMethodCall& message, async_reply_handler asyncReplyCallback)
|
||||
{
|
||||
// The new-ed handler gets deleted in the sdbus_async_reply_handler
|
||||
message.send((void*)&ObjectProxy::sdbus_async_reply_handler, new async_reply_handler(std::move(asyncReplyCallback)));
|
||||
auto callback = (void*)&ObjectProxy::sdbus_async_reply_handler;
|
||||
// Allocated userData gets deleted in the sdbus_async_reply_handler
|
||||
auto userData = new async_reply_handler(std::move(asyncReplyCallback));
|
||||
|
||||
connection_->callMethod(message, callback, userData);
|
||||
}
|
||||
|
||||
void ObjectProxy::registerSignalHandler( const std::string& interfaceName
|
||||
|
@@ -3,25 +3,25 @@
|
||||
# https://github.com/google/googletest/blob/master/googletest/README.md#incorporating-into-an-existing-cmake-project
|
||||
#-------------------------------
|
||||
|
||||
#configure_file(googletest-download/CMakeLists.txt.in googletest-download/CMakeLists.txt)
|
||||
configure_file(googletest-download/CMakeLists.txt.in googletest-download/CMakeLists.txt)
|
||||
|
||||
#execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
# RESULT_VARIABLE result
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download)
|
||||
|
||||
#if(result)
|
||||
# message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||
#endif()
|
||||
if(result)
|
||||
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||
endif()
|
||||
|
||||
#execute_process(COMMAND ${CMAKE_COMMAND} --build .
|
||||
# RESULT_VARIABLE result
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download)
|
||||
|
||||
#if(result)
|
||||
# message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
||||
#endif()
|
||||
if(result)
|
||||
message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
||||
endif()
|
||||
|
||||
#set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
|
||||
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
|
||||
@@ -63,8 +63,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
# targets even when INTERFACE_INCLUDE_DIRECTORIES is used.
|
||||
set(CMAKE_NO_SYSTEM_FROM_IMPORTED "1")
|
||||
|
||||
add_executable(libsdbus-c++_unittests ${UNITTESTS_SRCS} $<TARGET_OBJECTS:sdbuscppobjects>)
|
||||
target_link_libraries(libsdbus-c++_unittests ${SYSTEMD_LIBRARIES} gmock gmock_main)
|
||||
#add_executable(libsdbus-c++_unittests ${UNITTESTS_SRCS} $<TARGET_OBJECTS:sdbuscppobjects>)
|
||||
#target_link_libraries(libsdbus-c++_unittests ${SYSTEMD_LIBRARIES} gmock gmock_main)
|
||||
|
||||
add_executable(libsdbus-c++_integrationtests ${INTEGRATIONTESTS_SRCS})
|
||||
target_link_libraries(libsdbus-c++_integrationtests sdbus-c++ gmock gmock_main)
|
||||
@@ -82,7 +82,7 @@ endif()
|
||||
# INSTALLATION
|
||||
#----------------------------------
|
||||
|
||||
install(TARGETS libsdbus-c++_unittests DESTINATION /opt/test/bin)
|
||||
#install(TARGETS libsdbus-c++_unittests DESTINATION /opt/test/bin)
|
||||
install(TARGETS libsdbus-c++_integrationtests DESTINATION /opt/test/bin)
|
||||
install(FILES ${INTEGRATIONTESTS_SOURCE_DIR}/files/libsdbus-cpp-test.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d)
|
||||
|
||||
@@ -107,9 +107,9 @@ if(CMAKE_CROSSCOMPILING)
|
||||
if(NOT (UNIT_TESTS_RUNNER AND TEST_DEVICE_IP))
|
||||
message(WARNING "UNIT_TESTS_RUNNER and TEST_DEVICE_IP variables must be defined to run tests remotely")
|
||||
endif()
|
||||
add_test(NAME libsdbus-c++_unittests COMMAND ${UNIT_TESTS_RUNNER} --deviceip=${TEST_DEVICE_IP} --testbin=libsdbus-c++_unittests)
|
||||
#add_test(NAME libsdbus-c++_unittests COMMAND ${UNIT_TESTS_RUNNER} --deviceip=${TEST_DEVICE_IP} --testbin=libsdbus-c++_unittests)
|
||||
add_test(NAME libsdbus-c++_integrationtests COMMAND ${UNIT_TESTS_RUNNER} --deviceip=${TEST_DEVICE_IP} --testbin=libsdbus-c++_integrationtests)
|
||||
else()
|
||||
add_test(NAME libsdbus-c++_unittests COMMAND libsdbus-c++_unittests)
|
||||
#add_test(NAME libsdbus-c++_unittests COMMAND libsdbus-c++_unittests)
|
||||
add_test(NAME libsdbus-c++_integrationtests COMMAND libsdbus-c++_integrationtests)
|
||||
endif()
|
||||
|
Reference in New Issue
Block a user