pendingcall.cpp
Go to the documentation of this file.
1/*
2 *
3 * D-Bus++ - C++ bindings for D-Bus
4 *
5 * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
6 *
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
29
30#include <dbus/dbus.h>
31
32#include "internalerror.h"
33#include "pendingcall_p.h"
34#include "message_p.h"
35
36using namespace DBus;
37
38PendingCall::Private::Private(DBusPendingCall *dpc)
39 : call(dpc), dataslot(-1)
40{
41 if (!dbus_pending_call_allocate_data_slot(&dataslot))
42 {
43 throw ErrorNoMemory("Unable to allocate data slot");
44 }
45}
46
48{
49 if (dataslot != -1)
50 {
51 dbus_pending_call_allocate_data_slot(&dataslot);
52 }
53}
54
55void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data)
56{
57 PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
58
59 PendingCall pc(pvt);
60 pvt->slot(pc);
61}
62
64 : _pvt(p)
65{
66 if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
67 {
68 throw ErrorNoMemory("Unable to initialize pending call");
69 }
70}
71
73 : _pvt(c._pvt)
74{
75 dbus_pending_call_ref(_pvt->call);
76}
77
79{
80 dbus_pending_call_unref(_pvt->call);
81}
82
84{
85 if (&c != this)
86 {
87 dbus_pending_call_unref(_pvt->call);
88 _pvt = c._pvt;
89 dbus_pending_call_ref(_pvt->call);
90 }
91 return *this;
92}
93
95{
96 return dbus_pending_call_get_completed(_pvt->call);
97}
98
100{
101 dbus_pending_call_cancel(_pvt->call);
102}
103
105{
106 dbus_pending_call_block(_pvt->call);
107}
108
109void PendingCall::data(void *p)
110{
111 if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
112 {
113 throw ErrorNoMemory("Unable to initialize data slot");
114 }
115}
116
118{
119 return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
120}
121
123{
124 return _pvt->slot;
125}
126
128{
129 DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
130 if (!dmsg)
131 {
132 dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
133
134 if (callComplete)
135 throw ErrorNoReply("No reply available");
136 else
137 throw ErrorNoReply("Call not complete");
138 }
139
140 return Message(new Message::Private(dmsg));
141}
142
void cancel()
Cancels the pending call, such that any reply or error received will just be ignored.
Slot< void, PendingCall & > & slot()
Message steal_reply()
Gets the reply.
bool completed()
Checks whether the pending call has received a reply yet, or not.
PendingCall(Private *)
void data(void *data)
Stores a pointer on a PendingCall, along with an optional function to be used for freeing the data wh...
void * data()
Retrieves data previously set with dbus_pending_call_set_data().
void block()
Block until the pending call is completed.
PendingCall & operator=(const PendingCall &)
virtual ~PendingCall()
RefPtrI< Private > _pvt
Slot< void, PendingCall & > slot
static void notify_stub(DBusPendingCall *dpc, void *data)
Private(DBusPendingCall *)