* e_dbus: Don't unreference unitialized data. Thanks llvm.
[framework/uifw/edbus.git] / src / lib / dbus / e_dbus_message.c
1 #include <stdlib.h>
2 #include "E_DBus.h"
3 #include "e_dbus_private.h"
4
5 typedef struct E_DBus_Pending_Call_Data E_DBus_Pending_Call_Data;
6 struct E_DBus_Pending_Call_Data
7 {
8   E_DBus_Method_Return_Cb cb_return;
9   void                   *data;
10 };
11
12 static void
13 cb_pending(DBusPendingCall *pending, void *user_data)
14 {
15   DBusMessage *msg;
16   DBusError err;
17   E_DBus_Pending_Call_Data *data = user_data;
18
19   if (!dbus_pending_call_get_completed(pending))
20   {
21     INFO("E-dbus: NOT COMPLETED");
22     free(data);
23     dbus_pending_call_unref(pending);
24     return;
25   }
26
27   dbus_error_init(&err);
28   msg = dbus_pending_call_steal_reply(pending);
29   if (!msg)
30   {
31     if (data->cb_return)
32     {
33       dbus_set_error(&err, "org.enlightenment.DBus.NoReply", "There was no reply to this method call.");
34       data->cb_return(data->data, NULL, &err);
35       dbus_error_free(&err);
36     }
37     return;
38   }
39
40   if (dbus_set_error_from_message(&err, msg))
41   {
42     if (data->cb_return)
43       data->cb_return(data->data, NULL, &err);
44     dbus_error_free(&err);
45   }
46   else
47   {
48     if (data->cb_return)
49       data->cb_return(data->data, msg, &err);
50   }
51
52   dbus_message_unref(msg);
53   dbus_pending_call_unref(pending);
54 }
55
56
57 /**
58  * @brief Send a DBus message with callbacks
59  * @param conn The DBus connection
60  * @param msg  The message to send
61  * @param cb_return A callback function for returns (only used if @a msg is a method-call)
62  * @param timeout   A timeout in milliseconds, after which a synthetic error will be generated
63  * @return a DBusPendingCall that can be used to cancel the current call
64  */
65 EAPI DBusPendingCall *
66 e_dbus_message_send(E_DBus_Connection *conn, DBusMessage *msg, E_DBus_Method_Return_Cb cb_return, int timeout, void *data)
67 {
68   DBusPendingCall *pending;
69
70   if (!dbus_connection_send_with_reply(conn->conn, msg, &pending, timeout))
71     return NULL;
72
73   if (cb_return && pending)
74   {
75     E_DBus_Pending_Call_Data *pdata;
76
77     pdata = malloc(sizeof(E_DBus_Pending_Call_Data));
78     pdata->cb_return = cb_return;
79     pdata->data = data;
80
81     if (!dbus_pending_call_set_notify(pending, cb_pending, pdata, free))
82     {
83       free(pdata);
84       dbus_message_unref(msg);
85       dbus_pending_call_cancel(pending);
86       return NULL;
87     }
88   }
89
90   return pending;
91 }
92
93 static void
94 cb_method_call(void *data, DBusMessage *msg, DBusError *err)
95 {
96   E_DBus_Callback *cb = data;
97   void *method_return = NULL;
98   DBusError new_err;
99   if (!cb) return;
100
101   dbus_error_init(&new_err);
102   if (!dbus_error_is_set(err))
103     method_return = e_dbus_callback_unmarshal(cb, msg, &new_err);
104   else
105     dbus_move_error(err, &new_err);
106
107   e_dbus_callback_call(cb, method_return, &new_err);
108   e_dbus_callback_return_free(cb, method_return);
109
110   if (dbus_error_is_set(&new_err))
111     dbus_error_free(&new_err);
112
113   e_dbus_callback_free(cb);
114 }
115
116 EAPI DBusPendingCall *
117 e_dbus_method_call_send(E_DBus_Connection *conn, DBusMessage *msg, E_DBus_Unmarshal_Func unmarshal_func, E_DBus_Callback_Func cb_func, E_DBus_Free_Func free_func, int timeout, void *data)
118 {
119   E_DBus_Callback *cb;
120   cb = e_dbus_callback_new(cb_func, unmarshal_func, free_func, data);
121   return e_dbus_message_send(conn, msg, cb_method_call, timeout, cb);
122 }