forked from Kistler-Group/sdbus-cpp
Compare commits
7 Commits
v1.2.0
...
fix_deprec
Author | SHA1 | Date | |
---|---|---|---|
e199dc58cf | |||
ad7731d900 | |||
101dd1c2ba | |||
299e6940cd | |||
3f825ffb30 | |||
35bffd0f25 | |||
e33a890ce7 |
@ -81,6 +81,7 @@ set(SDBUSCPP_PUBLIC_HDRS
|
|||||||
${SDBUSCPP_INCLUDE_DIR}/Types.h
|
${SDBUSCPP_INCLUDE_DIR}/Types.h
|
||||||
${SDBUSCPP_INCLUDE_DIR}/TypeTraits.h
|
${SDBUSCPP_INCLUDE_DIR}/TypeTraits.h
|
||||||
${SDBUSCPP_INCLUDE_DIR}/Flags.h
|
${SDBUSCPP_INCLUDE_DIR}/Flags.h
|
||||||
|
${SDBUSCPP_INCLUDE_DIR}/SdbusAsio.h
|
||||||
${SDBUSCPP_INCLUDE_DIR}/sdbus-c++.h)
|
${SDBUSCPP_INCLUDE_DIR}/sdbus-c++.h)
|
||||||
|
|
||||||
set(SDBUSCPP_SRCS ${SDBUSCPP_CPP_SRCS} ${SDBUSCPP_HDR_SRCS} ${SDBUSCPP_PUBLIC_HDRS})
|
set(SDBUSCPP_SRCS ${SDBUSCPP_CPP_SRCS} ${SDBUSCPP_HDR_SRCS} ${SDBUSCPP_PUBLIC_HDRS})
|
||||||
@ -210,6 +211,11 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/sdbus-c++-config.cmake
|
|||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sdbus-c++
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sdbus-c++
|
||||||
COMPONENT dev)
|
COMPONENT dev)
|
||||||
|
|
||||||
|
if(BUILD_SHARED_LIBS AND (BUILD_LIBSYSTEMD OR Systemd_LINK_LIBRARIES MATCHES "/libsystemd\.a(;|$)"))
|
||||||
|
set(PKGCONFIG_REQS ".private")
|
||||||
|
else()
|
||||||
|
set(PKGCONFIG_REQS "")
|
||||||
|
endif()
|
||||||
configure_file(pkgconfig/sdbus-c++.pc.in pkgconfig/sdbus-c++.pc @ONLY)
|
configure_file(pkgconfig/sdbus-c++.pc.in pkgconfig/sdbus-c++.pc @ONLY)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/sdbus-c++.pc
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/sdbus-c++.pc
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT dev)
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT dev)
|
||||||
|
@ -41,7 +41,7 @@ Typical default D-Bus configuration does not allow to register services except e
|
|||||||
<busconfig>
|
<busconfig>
|
||||||
<policy user="root">
|
<policy user="root">
|
||||||
<allow own="org.sdbuscpp.concatenator"/>
|
<allow own="org.sdbuscpp.concatenator"/>
|
||||||
<allow send_destination="org.sdbuscpp"/>
|
<allow send_destination="org.sdbuscpp.concatenator"/>
|
||||||
<allow send_interface="org.sdbuscpp.concatenator"/>
|
<allow send_interface="org.sdbuscpp.concatenator"/>
|
||||||
</policy>
|
</policy>
|
||||||
</busconfig>
|
</busconfig>
|
||||||
|
@ -78,6 +78,11 @@ namespace sdbus {
|
|||||||
*/
|
*/
|
||||||
uint64_t timeout_usec;
|
uint64_t timeout_usec;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The read fd to be monitored by the event loop.
|
||||||
|
*/
|
||||||
|
int event_fd;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Get the event poll timeout.
|
* Get the event poll timeout.
|
||||||
*
|
*
|
||||||
|
67
include/sdbus-c++/SdbusAsio.h
Normal file
67
include/sdbus-c++/SdbusAsio.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
|
||||||
|
class SdbusAsio final : boost::noncopyable {
|
||||||
|
public:
|
||||||
|
explicit SdbusAsio(boost::asio::io_context& io_context,
|
||||||
|
std::unique_ptr<sdbus::IConnection> conn = sdbus::createDefaultBusConnection())
|
||||||
|
: conn_ { std::move(conn) }
|
||||||
|
, timer_ { io_context }
|
||||||
|
, dbus_desc_ { io_context }
|
||||||
|
, event_desc_ { io_context }
|
||||||
|
|
||||||
|
{
|
||||||
|
auto poll_data = conn_->getEventLoopPollData();
|
||||||
|
dbus_desc_.async_wait(boost::asio::posix::stream_descriptor::wait_read,
|
||||||
|
[this](const boost::system::error_code&) { processRead(); });
|
||||||
|
dbus_desc_.assign(poll_data.fd);
|
||||||
|
|
||||||
|
event_desc_.async_read_some(boost::asio::null_buffers(), [this](auto&, auto) { processEvent(); });
|
||||||
|
event_desc_.assign(poll_data.event_fd);
|
||||||
|
|
||||||
|
if (poll_data.timeout_usec != UINT64_MAX) {
|
||||||
|
timer_.async_wait([this](boost::system::error_code const&) { processTimeout(); });
|
||||||
|
timer_.expires_after(boost::posix_time::microsec(poll_data.timeout_usec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<sdbus::IConnection> getConnection() { return conn_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void process()
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < DBUS_PROCESS_MAX; i++) {
|
||||||
|
if (!conn_->processPendingRequest()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void processRead()
|
||||||
|
{
|
||||||
|
process();
|
||||||
|
dbus_desc_.async_wait(boost::asio::posix::stream_descriptor::wait_read,
|
||||||
|
[this](const boost::system::error_code&) { processRead(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void processEvent()
|
||||||
|
{
|
||||||
|
process();
|
||||||
|
event_desc_.async_read_some(boost::asio::null_buffers(), [this](auto, auto) { processEvent(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void processTimeout()
|
||||||
|
{
|
||||||
|
process();
|
||||||
|
timer_.async_wait([this](boost::system::error_code const&) { processTimeout(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr auto DBUS_PROCESS_MAX = 32;
|
||||||
|
std::shared_ptr<sdbus::IConnection> conn_;
|
||||||
|
boost::asio::deadline_timer timer_;
|
||||||
|
boost::asio::posix::stream_descriptor dbus_desc_;
|
||||||
|
boost::asio::posix::stream_descriptor event_desc_;
|
||||||
|
};
|
@ -5,7 +5,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
|||||||
|
|
||||||
Name: @PROJECT_NAME@
|
Name: @PROJECT_NAME@
|
||||||
Description: C++ library on top of sd-bus, a systemd D-Bus library
|
Description: C++ library on top of sd-bus, a systemd D-Bus library
|
||||||
Requires: libsystemd
|
Requires@PKGCONFIG_REQS@: libsystemd
|
||||||
Version: @SDBUSCPP_VERSION@
|
Version: @SDBUSCPP_VERSION@
|
||||||
Libs: -L${libdir} -l@PROJECT_NAME@
|
Libs: -L${libdir} -l@PROJECT_NAME@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
@ -75,11 +75,16 @@ Connection::Connection(std::unique_ptr<ISdBus>&& interface, pseudo_bus_t)
|
|||||||
, bus_(openPseudoBus())
|
, bus_(openPseudoBus())
|
||||||
{
|
{
|
||||||
assert(iface_ != nullptr);
|
assert(iface_ != nullptr);
|
||||||
|
eventFd_.fd = eventfd(0, 0);
|
||||||
|
assert(eventFd_.fd >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection::~Connection()
|
Connection::~Connection()
|
||||||
{
|
{
|
||||||
Connection::leaveEventLoop();
|
Connection::leaveEventLoop();
|
||||||
|
if (0 <= eventFd_.fd) {
|
||||||
|
close(eventFd_.fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::requestName(const std::string& name)
|
void Connection::requestName(const std::string& name)
|
||||||
@ -141,7 +146,7 @@ Connection::PollData Connection::getEventLoopPollData() const
|
|||||||
auto r = iface_->sd_bus_get_poll_data(bus_.get(), &pollData);
|
auto r = iface_->sd_bus_get_poll_data(bus_.get(), &pollData);
|
||||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to get bus poll data", -r);
|
SDBUS_THROW_ERROR_IF(r < 0, "Failed to get bus poll data", -r);
|
||||||
|
|
||||||
return {pollData.fd, pollData.events, pollData.timeout_usec};
|
return {pollData.fd, pollData.events, pollData.timeout_usec, eventFd_.fd};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ISdBus& Connection::getSdBusInterface() const
|
const ISdBus& Connection::getSdBusInterface() const
|
||||||
@ -445,6 +450,11 @@ void Connection::notifyEventLoopToExit() const
|
|||||||
notifyEventLoop(loopExitFd_.fd);
|
notifyEventLoop(loopExitFd_.fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Connection::notifyEventLoop() const
|
||||||
|
{
|
||||||
|
notifyEventLoop(eventFd_.fd);
|
||||||
|
}
|
||||||
|
|
||||||
void Connection::notifyEventLoopNewTimeout() const
|
void Connection::notifyEventLoopNewTimeout() const
|
||||||
{
|
{
|
||||||
// The extra notifications for new timeouts are only needed if calls are made asynchronously to the event loop.
|
// The extra notifications for new timeouts are only needed if calls are made asynchronously to the event loop.
|
||||||
|
@ -139,6 +139,7 @@ namespace sdbus::internal {
|
|||||||
void notifyEventLoop(int fd) const;
|
void notifyEventLoop(int fd) const;
|
||||||
void notifyEventLoopToExit() const;
|
void notifyEventLoopToExit() const;
|
||||||
void clearEventLoopNotification(int fd) const;
|
void clearEventLoopNotification(int fd) const;
|
||||||
|
void notifyEventLoop() const override;
|
||||||
void notifyEventLoopNewTimeout() const override;
|
void notifyEventLoopNewTimeout() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -90,6 +90,7 @@ namespace sdbus::internal {
|
|||||||
, sd_bus_message_handler_t callback
|
, sd_bus_message_handler_t callback
|
||||||
, void* userData ) = 0;
|
, void* userData ) = 0;
|
||||||
|
|
||||||
|
virtual void notifyEventLoop() const = 0;
|
||||||
virtual void notifyEventLoopNewTimeout() const = 0;
|
virtual void notifyEventLoopNewTimeout() const = 0;
|
||||||
virtual MethodReply tryCallMethodSynchronously(const MethodCall& message, uint64_t timeout) = 0;
|
virtual MethodReply tryCallMethodSynchronously(const MethodCall& message, uint64_t timeout) = 0;
|
||||||
};
|
};
|
||||||
|
@ -782,6 +782,10 @@ MethodReply MethodCall::sendWithReply(uint64_t timeout) const
|
|||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
||||||
|
|
||||||
|
// Force event loop to re-enter processing to handle queued messages
|
||||||
|
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||||
|
connection_->notifyEventLoop();
|
||||||
|
|
||||||
return Factory::create<MethodReply>(sdbusReply, sdbus_, adopt_message);
|
return Factory::create<MethodReply>(sdbusReply, sdbus_, adopt_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +794,10 @@ MethodReply MethodCall::sendWithNoReply() const
|
|||||||
auto r = sdbus_->sd_bus_send(nullptr, (sd_bus_message*)msg_, nullptr);
|
auto r = sdbus_->sd_bus_send(nullptr, (sd_bus_message*)msg_, nullptr);
|
||||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method with no reply", -r);
|
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method with no reply", -r);
|
||||||
|
|
||||||
|
// Force event loop to re-enter processing to handle queued messages
|
||||||
|
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||||
|
connection_->notifyEventLoop();
|
||||||
|
|
||||||
return Factory::create<MethodReply>(); // No reply
|
return Factory::create<MethodReply>(); // No reply
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,12 +292,12 @@ void Document::Expat::character_data_handler(void* data, const XML_Char* chars,
|
|||||||
nod = &(nod->children.back());
|
nod = &(nod->children.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = 0, y = len - 1;
|
int offset = 0, count = len;
|
||||||
|
|
||||||
while (isspace(chars[y]) && y > 0) --y;
|
while (count > 0 && isspace(chars[count - 1])) --count;
|
||||||
while (isspace(chars[x]) && x < y) ++x;
|
while (offset < count && isspace(chars[offset])) { ++offset; --count; }
|
||||||
|
|
||||||
nod->cdata = std::string(chars, x, y + 1);
|
nod->cdata = std::string{chars + offset, static_cast<std::string::size_type>(count)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::Expat::end_element_handler(void* data, const XML_Char* /*name*/)
|
void Document::Expat::end_element_handler(void* data, const XML_Char* /*name*/)
|
||||||
|
Reference in New Issue
Block a user