【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
    评论
`g_dbus_proxy_call_sync` 是 GLib 库中用于同步调用 D-Bus 代理对象方法的函数。它允许您在 D-Bus 上进行同步的方法调用,并等待方法调用的完成。 函数原型如下: ```c gboolean g_dbus_proxy_call_sync (GDBusProxy *proxy, const gchar *method_name, GVariant *parameters, GDBusCallFlags flags, gint timeout_msec, GCancellable *cancellable, GError **error); ``` 参数说明: - `proxy`:要调用方法的 D-Bus 代理对象。 - `method_name`:要调用的方法名称。 - `parameters`:方法调用的参数,使用 GVariant 类型。 - `flags`:调用标志,可以是 `G_DBUS_CALL_FLAGS_NONE` 或其他标志。 - `timeout_msec`:超时时间(以毫秒为单位),如果设置为 -1,则表示不设置超时。 - `cancellable`:可选的 GCancellable 对象,用于取消方法调用。 - `error`:如果发生错误,将在此处返回错误信息。 函数返回值为 `gboolean` 类型,表示方法调用是否成功。如果成功,返回 `TRUE`,否则返回 `FALSE`。 使用 `g_dbus_proxy_call_sync` 函数时,首先需要获取一个 D-Bus 代理对象,可以使用 `g_dbus_proxy_new_sync` 函数来创建。然后,通过调用 `g_dbus_proxy_call_sync` 来执行同步的方法调用。 这个函数可以方便地与 D-Bus 服务进行通信,但需要注意的是,它会阻塞当前线程,直到方法调用完成或超时。如果需要异步的方法调用,可以考虑使用 `g_dbus_proxy_call` 函数。 您可以参考 GLib 的文档以获取更详细的信息和示例代码:[GLib D-Bus API 文档](https://developer.gnome.org/gio/stable/gdbus-proxy.html#g-dbus-proxy-call-sync) 希望这能帮助到您!如果你有更多问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值