【sdbusctl系列】D-Bus的同步调用与异步调用函数

前面

本文章描述D-Bus同步调用函数与异步调用函数。

D-Bus函数调用

同步调用

new_method_call

需要判断返回值情况:

uint32_t commit(const char* name)
{
    using phosphor::logging::log;
    auto bus = sdbusplus::bus::new_default();
    auto method = bus.new_method_call("xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging/internel/manager", "xyz.openbmc_project.Logging.Internal.Manager", "Commit");
    uint64_t id = sdbusplus::server::transaction::get_id();
    method.append(id, name);
    auto reply = bus.call(method);
    uint32_t entryID;
    reply.read(entryID);
    return entryID;
}

无需判断返回值情况:

void commit(const char* name)
{
    using phosphor::logging::log;
    auto bus = sdbusplus::bus::new_default();
    auto method = bus.new_method_call("xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging/internel/manager", "xyz.openbmc_project.Logging.Internal.Manager", "Commit");
    uint64_t id = sdbusplus::server::transaction::get_id();
    method.append(id, name);
    auto reply = bus.call_noreply(method);
    return ;
}

异步调用

通常与lambda表达式混合使用。

async_method_call

static boost::asio::io_context io;
std::shared_ptr<sdbusplus::asio::connection> conn;
static void beep(const uint8_t& beepPriority)
{
    lg2::info("Beep with priority: {BEEP_PRIORITY}", "BEEP_PRIORITY",
              beepPriority);
    conn->async_method_call(
        [](boost::system::error_code ec) {
        if (ec)
        {
            lg2::error(
                "beep returned error with async_method_call (ec = {ERROR_MSG})",
                "ERROR_MSG", ec.message());
            return;
        }
        },
        "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode",
        "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority));
}

yield_method_call

yield_method_call 方法实际上是一个异步的方法。它使用的是 asio 库中的异步操作和协程机制。
通过使用 yield_method_call 方法可以在异步环境中执行 DBus 方法调用,并在方法调用完成后恢复协程的执行。这种调用方式允许程序在等待方法调用结果时不会阻塞主线程,而是继续处理其他任务。可以理解为yield_method_call在响应之前会处于等待的状态。

 void handleLegacyIpmiCommand(sdbusplus::message_t& m)
{
     // make a copy so the next two moves don't wreak havoc on the stack
     sdbusplus::message_t b{m};
     boost::asio::spawn(*getIoContext(),
                      [b = std::move(b)](boost::asio::yield_context yield) {
     sdbusplus::message_t m{std::move(b)};
     unsigned char seq = 0, netFn = 0, lun = 0, cmd = 0;
     ipmi::SecureBuffer data;
     m.read(seq, netFn, lun, cmd, data);
     std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
     auto ctx = std::make_shared<ipmi::Context>(bus, netFn, lun, cmd, 0, 0, 0, ipmi::Privilege::Admin, 0, 0, yield);
     auto request = std::make_shared<ipmi::message::Request>(ctx, std::forward<ipmi::SecureBuffer>(data));
     ipmi::message::Response::ptr response =  ipmi::executeIpmiCommand(request);
      // Responses in IPMI require a bit set.  So there ya go...
      netFn |= 0x01;
      const char *dest, *path;
      constexpr const char* DBUS_INTF = "org.openbmc.HostIpmi";

      dest = m.get_sender();
      path = m.get_path();
      boost::system::error_code ec;
      bus->yield_method_call(yield, ec, dest, path, DBUS_INTF, "sendMessage",
                               seq, netFn, lun, cmd, response->cc,
                               response->payload.raw);
      if (ec)
      {
            log<level::ERR>("Failed to send response to requestor",
                            entry("ERROR=%s", ec.message().c_str()),
                            entry("SENDER=%s", dest),
                            entry("NETFN=0x%X", netFn), entry("CMD=0x%X", cmd));
        }
    });
}
  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值