00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <dbus-c++/pendingcall.h>
00029
00030 #include <dbus/dbus.h>
00031
00032 #include "internalerror.h"
00033 #include "pendingcall_p.h"
00034 #include "message_p.h"
00035
00036 using namespace DBus;
00037
00038 PendingCall::Private::Private(DBusPendingCall *dpc)
00039 : call(dpc), dataslot(-1)
00040 {
00041 if (!dbus_pending_call_allocate_data_slot(&dataslot))
00042 {
00043 throw ErrorNoMemory("Unable to allocate data slot");
00044 }
00045 }
00046
00047 PendingCall::Private::~Private()
00048 {
00049 if (dataslot != -1)
00050 {
00051 dbus_pending_call_allocate_data_slot(&dataslot);
00052 }
00053 }
00054
00055 void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data)
00056 {
00057 PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
00058
00059 PendingCall pc(pvt);
00060 pvt->slot(pc);
00061 }
00062
00063 PendingCall::PendingCall(PendingCall::Private *p)
00064 : _pvt(p)
00065 {
00066 if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
00067 {
00068 throw ErrorNoMemory("Unable to initialize pending call");
00069 }
00070 }
00071
00072 PendingCall::PendingCall(const PendingCall &c)
00073 : _pvt(c._pvt)
00074 {
00075 dbus_pending_call_ref(_pvt->call);
00076 }
00077
00078 PendingCall::~PendingCall()
00079 {
00080 dbus_pending_call_unref(_pvt->call);
00081 }
00082
00083 PendingCall &PendingCall::operator = (const PendingCall &c)
00084 {
00085 if (&c != this)
00086 {
00087 dbus_pending_call_unref(_pvt->call);
00088 _pvt = c._pvt;
00089 dbus_pending_call_ref(_pvt->call);
00090 }
00091 return *this;
00092 }
00093
00094 bool PendingCall::completed()
00095 {
00096 return dbus_pending_call_get_completed(_pvt->call);
00097 }
00098
00099 void PendingCall::cancel()
00100 {
00101 dbus_pending_call_cancel(_pvt->call);
00102 }
00103
00104 void PendingCall::block()
00105 {
00106 dbus_pending_call_block(_pvt->call);
00107 }
00108
00109 void PendingCall::data(void *p)
00110 {
00111 if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
00112 {
00113 throw ErrorNoMemory("Unable to initialize data slot");
00114 }
00115 }
00116
00117 void *PendingCall::data()
00118 {
00119 return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
00120 }
00121
00122 Slot<void, PendingCall &>& PendingCall::slot()
00123 {
00124 return _pvt->slot;
00125 }
00126
00127 Message PendingCall::steal_reply()
00128 {
00129 DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
00130 if (!dmsg)
00131 {
00132 dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
00133
00134 if (callComplete)
00135 throw ErrorNoReply("No reply available");
00136 else
00137 throw ErrorNoReply("Call not complete");
00138 }
00139
00140 return Message(new Message::Private(dmsg));
00141 }
00142