Files
2026-09-22 09:38:26 +08:00

126 lines
3.1 KiB
C++

/*
* SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0
* Copyright 2016-2023 Unisoc (Shanghai) Technologies Co., Ltd
* Licensed under the Unisoc General Software License, version 1.0 (the License);
* you may not use this file except in compliance with the License. You may obtain a copy of the License at
* https://www.unisoc.com/en_us/license/UNISOC_GENERAL_LICENSE_V1.0-EN_US
* Software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, either express or implied.
* See the Unisoc General Software License, version 1.0 for more details.
*/
#include <Pendingcall.h>
#include <Debug.h>
#include <dbus/dbus.h>
#include "InternalError.h"
#include "PendingcallInternal.h"
#include "MessageInternal.h"
using namespace UDBus;
PendingCall::UDBusPrivate::UDBusPrivate(DBusPendingCall *dpc)
: call(dpc), dataslot(-1)
{
if (!dbus_pending_call_allocate_data_slot(&dataslot))
throw ErrorNoMemory("Unable to allocate data slot");
}
PendingCall::UDBusPrivate::~UDBusPrivate()
{
if (dataslot != -1) {
dbus_pending_call_free_data_slot(&dataslot);
}
}
void PendingCall::UDBusPrivate::notify_stub(DBusPendingCall *dpc, void *data)
{
DEBUG("dpc[%p]", dpc);
PendingCall *pc = static_cast<PendingCall *>(data);
pc->mPrivate->ReplyHandler(pc);
}
PendingCall::PendingCall(PendingCall::UDBusPrivate *p)
: mPrivate(p)
{
if (!dbus_pending_call_set_notify(mPrivate->call, UDBusPrivate::notify_stub, this, nullptr)) {
throw ErrorNoMemory("Unable to initialize pending call");
}
}
PendingCall::PendingCall(const PendingCall &c)
: mPrivate(c.mPrivate)
{
dbus_pending_call_ref(mPrivate->call);
}
PendingCall::~PendingCall()
{
dbus_pending_call_unref(mPrivate->call);
}
PendingCall &PendingCall::operator = (const PendingCall &c)
{
if (&c != this) {
dbus_pending_call_unref(mPrivate->call);
mPrivate = c.mPrivate;
dbus_pending_call_ref(mPrivate->call);
}
return *this;
}
bool PendingCall::Completed()
{
return dbus_pending_call_get_completed(mPrivate->call);
}
void PendingCall::Cancel()
{
dbus_pending_call_cancel(mPrivate->call);
}
void PendingCall::Block()
{
dbus_pending_call_block(mPrivate->call);
}
void PendingCall::Data(void *p)
{
if (!dbus_pending_call_set_data(mPrivate->call, mPrivate->dataslot, p, nullptr))
throw ErrorNoMemory("Unable to initialize data slot");
}
void *PendingCall::Data()
{
return dbus_pending_call_get_data(mPrivate->call, mPrivate->dataslot);
}
AsyncReplyHandler &PendingCall::ReplyHandler()
{
return mPrivate->ReplyHandler;
}
void PendingCall::ReplyHandler(const AsyncReplyHandler &handler)
{
mPrivate->ReplyHandler = handler;
}
Message PendingCall::StealReply()
{
DBusMessage *dmsg = dbus_pending_call_steal_reply(mPrivate->call);
if (!dmsg) {
dbus_bool_t callComplete = dbus_pending_call_get_completed(mPrivate->call);
if (callComplete)
throw ErrorNoReply("No reply available");
else
throw ErrorNoReply("Call not complete");
}
return Message(new Message::UDBusPrivate(dmsg));
}