1 #include "eldbus_private.h"
2 #include "eldbus_private_types.h"
5 /* TODO: mempool of Eldbus_Pending */
6 #define ELDBUS_PENDING_CHECK(pending) \
9 EINA_SAFETY_ON_NULL_RETURN(pending); \
10 if (!EINA_MAGIC_CHECK(pending, ELDBUS_PENDING_MAGIC)) \
12 EINA_MAGIC_FAIL(pending, ELDBUS_PENDING_MAGIC); \
18 #define ELDBUS_PENDING_CHECK_RETVAL(pending, retval) \
21 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, retval); \
22 if (!EINA_MAGIC_CHECK(pending, ELDBUS_PENDING_MAGIC)) \
24 EINA_MAGIC_FAIL(pending, ELDBUS_PENDING_MAGIC); \
30 static void eldbus_pending_dispatch(Eldbus_Pending *pending, Eldbus_Message *msg);
33 eldbus_pending_init(void)
39 eldbus_pending_shutdown(void)
44 cb_pending(DBusPendingCall *dbus_pending, void *user_data)
47 Eldbus_Pending *pending = user_data;
49 if (!dbus_pending_call_get_completed(dbus_pending))
51 INF("timeout to pending %p", pending);
52 dbus_pending_call_cancel(dbus_pending);
53 msg = eldbus_message_error_new(pending->msg_sent,
54 "org.enlightenment.DBus.Timeout",
55 "This call was not completed.");
56 eldbus_pending_dispatch(pending, msg);
60 msg = eldbus_message_new(EINA_FALSE);
61 EINA_SAFETY_ON_NULL_RETURN(msg);
62 msg->dbus_msg = dbus_pending_call_steal_reply(dbus_pending);
65 EINA_SAFETY_ON_NULL_GOTO(pending->cb, cleanup);
67 msg->dbus_msg = dbus_message_new_error(NULL,
68 "org.enlightenment.DBus.NoReply",
69 "There was no reply to this method call.");
70 EINA_SAFETY_ON_NULL_GOTO(msg->dbus_msg, cleanup);
73 dbus_message_iter_init(msg->dbus_msg, &msg->iterator->dbus_iterator);
74 eldbus_pending_dispatch(pending, msg);
79 eldbus_message_unref(msg);
83 _on_pending_free(void *data, const void *dead_pointer)
85 Eldbus_Connection *conn = data;
86 eldbus_connection_pending_del(conn, (void *)dead_pointer);
90 eldbus_connection_send(Eldbus_Connection *conn, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout)
92 Eldbus_Pending *pending;
94 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
95 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
97 pending = _eldbus_connection_send(conn, msg, cb, cb_data, timeout);
99 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
101 eldbus_connection_pending_add(conn, pending);
102 eldbus_pending_free_cb_add(pending, _on_pending_free, conn);
107 _eldbus_connection_send(Eldbus_Connection *conn, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout)
109 Eldbus_Pending *pending;
110 Eldbus_Message *error_msg;
111 DBG("conn=%p, msg=%p, cb=%p, cb_data=%p, timeout=%f",
112 conn, msg, cb, cb_data, timeout);
116 dbus_connection_send(conn->dbus_conn, msg->dbus_msg, NULL);
120 pending = calloc(1, sizeof(Eldbus_Pending));
121 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
124 pending->cb_data = cb_data;
125 pending->conn = conn;
126 pending->dest = eina_stringshare_add(dbus_message_get_member(msg->dbus_msg));
127 pending->interface = eina_stringshare_add(dbus_message_get_interface(msg->dbus_msg));
128 pending->method = eina_stringshare_add(dbus_message_get_member(msg->dbus_msg));
129 pending->path = eina_stringshare_add(dbus_message_get_path(msg->dbus_msg));
130 pending->msg_sent = eldbus_message_ref(msg);
131 EINA_MAGIC_SET(pending, ELDBUS_PENDING_MAGIC);
133 if (!dbus_connection_send_with_reply(conn->dbus_conn,
135 &pending->dbus_pending, timeout))
137 error_msg = eldbus_message_error_new(msg, "org.enlightenment.DBus.NoConnection",
138 "Eldbus_Connection was closed.");
139 eldbus_pending_dispatch(pending, error_msg);
142 if (dbus_pending_call_set_notify(pending->dbus_pending, cb_pending, pending, NULL))
145 dbus_pending_call_cancel(pending->dbus_pending);
146 error_msg = eldbus_message_error_new(pending->msg_sent,
147 "org.enlightenment.DBus.Error",
148 "Error when try set callback to message.");
149 eldbus_pending_dispatch(pending, error_msg);
154 eldbus_pending_data_set(Eldbus_Pending *pending, const char *key, const void *data)
156 ELDBUS_PENDING_CHECK(pending);
157 EINA_SAFETY_ON_NULL_RETURN(key);
158 EINA_SAFETY_ON_NULL_RETURN(data);
159 eldbus_data_set(&(pending->data), key, data);
163 eldbus_pending_data_get(const Eldbus_Pending *pending, const char *key)
165 ELDBUS_PENDING_CHECK_RETVAL(pending, NULL);
166 EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
167 return eldbus_data_get(&(((Eldbus_Pending *)pending)->data), key);
171 eldbus_pending_data_del(Eldbus_Pending *pending, const char *key)
173 ELDBUS_PENDING_CHECK_RETVAL(pending, NULL);
174 EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
175 return eldbus_data_del(&(((Eldbus_Pending *)pending)->data), key);
179 eldbus_pending_dispatch(Eldbus_Pending *pending, Eldbus_Message *msg)
181 DBG("pending=%p msg=%p", pending, msg);
183 pending->cb((void *)pending->cb_data, msg, pending);
185 eldbus_cbs_free_dispatch(&(pending->cbs_free), pending);
186 eldbus_data_del_all(&(pending->data));
188 if (msg) eldbus_message_unref(msg);
189 eldbus_message_unref(pending->msg_sent);
190 dbus_pending_call_unref(pending->dbus_pending);
193 pending->dbus_pending = NULL;
194 eina_stringshare_del(pending->dest);
195 eina_stringshare_del(pending->path);
196 eina_stringshare_del(pending->interface);
197 eina_stringshare_del(pending->method);
198 EINA_MAGIC_SET(pending, EINA_MAGIC_NONE);
203 eldbus_pending_cancel(Eldbus_Pending *pending)
205 Eldbus_Message *error_message;
206 ELDBUS_PENDING_CHECK(pending);
207 EINA_SAFETY_ON_NULL_RETURN(pending->dbus_pending);
209 DBG("pending=%p", pending);
210 dbus_pending_call_cancel(pending->dbus_pending);
212 error_message = eldbus_message_error_new(pending->msg_sent,
213 "org.enlightenment.DBus.Canceled",
214 "Canceled by user.");
215 eldbus_pending_dispatch(pending, error_message);
219 eldbus_pending_free_cb_add(Eldbus_Pending *pending, Eldbus_Free_Cb cb, const void *data)
221 ELDBUS_PENDING_CHECK(pending);
222 EINA_SAFETY_ON_NULL_RETURN(cb);
223 pending->cbs_free = eldbus_cbs_free_add(pending->cbs_free, cb, data);
227 eldbus_pending_free_cb_del(Eldbus_Pending *pending, Eldbus_Free_Cb cb, const void *data)
229 ELDBUS_PENDING_CHECK(pending);
230 EINA_SAFETY_ON_NULL_RETURN(cb);
231 pending->cbs_free = eldbus_cbs_free_del(pending->cbs_free, cb, data);
235 eldbus_pending_destination_get(const Eldbus_Pending *pending)
237 ELDBUS_PENDING_CHECK_RETVAL(pending, NULL);
238 return pending->dest;
242 eldbus_pending_path_get(const Eldbus_Pending *pending)
244 ELDBUS_PENDING_CHECK_RETVAL(pending, NULL);
245 return pending->path;
249 eldbus_pending_interface_get(const Eldbus_Pending *pending)
251 ELDBUS_PENDING_CHECK_RETVAL(pending, NULL);
252 return pending->interface;
256 eldbus_pending_method_get(const Eldbus_Pending *pending)
258 ELDBUS_PENDING_CHECK_RETVAL(pending, NULL);
259 return pending->method;