/* * 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 #include #include #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(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)); }