126 lines
3.1 KiB
C++
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));
|
|
}
|