soc.2010.detachablepurple: ab50e1b4: Modified the PurpleDBusCallback.requests...
gillux at soc.pidgin.im
gillux at soc.pidgin.im
Sat Jul 31 01:35:56 EDT 2010
----------------------------------------------------------------------
Revision: ab50e1b4f036e18affccfeec5cde5cb4f6e4e106
Parent: 3bd0a8862c2036a2b8746566f8c1abcb84084d8c
Author: gillux at soc.pidgin.im
Date: 07/31/10 00:19:47
Branch: im.pidgin.soc.2010.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/ab50e1b4f036e18affccfeec5cde5cb4f6e4e106
Changelog:
Modified the PurpleDBusCallback.requests hash table. It is still used as before
by the daemon, but the clients will use the new client_reqs hash table, which
is more appropriate, since the clients would never register closures others
than the closing one.
Modified purple_callback_register_req_id() to match this.
We also use this us to save the client handle, which will be useful to get the
request id from, as the new purple_callback_get_req_id() allows us to do.
Changes against parent 3bd0a8862c2036a2b8746566f8c1abcb84084d8c
patched libpurple/account-dbus.c
patched libpurple/dbus-callback.c
patched libpurple/dbus-callback.h
-------------- next part --------------
============================================================
--- libpurple/account-dbus.c 2b3bd88b46773c3376270cc2f62f8f343d42febe
+++ libpurple/account-dbus.c 65c88b7a3c875a03bc6152e432e45d863c9bdca1
@@ -98,7 +98,7 @@ request_authorize_cb(DBusGProxy *proxy,
G_CALLBACK(purple_account_request_close),
h, NULL);
g_closure_set_marshal(close_req, purple_nullmarshaller);
- purple_callback_register_req_id(request_id, 1, close_req);
+ purple_callback_register_req_id(request_id, close_req, h);
}
}
============================================================
--- libpurple/dbus-callback.c 97c85b6bfa791e4150a183b86b730294ed3e305b
+++ libpurple/dbus-callback.c 6f66005a71c2a9cc8f5225eeab40cedee8233846
@@ -125,7 +125,10 @@ purple_dbus_callback_finalize(GObject *s
klass = g_type_class_peek(PURPLE_TYPE_DBUS_CALLBACK);
klass->instance = NULL;
g_hash_table_destroy(PURPLE_DBUS_CALLBACK(self)->callbacks);
- g_hash_table_destroy(PURPLE_DBUS_CALLBACK(self)->requests);
+ if (purple_core_is_daemon_mode())
+ g_hash_table_destroy(PURPLE_DBUS_CALLBACK(self)->requests);
+ if (purple_core_is_remote_mode())
+ g_hash_table_destroy(PURPLE_DBUS_CALLBACK(self)->client_reqs);
G_OBJECT_CLASS(purple_dbus_callback_parent_class)->finalize(self);
}
@@ -161,14 +164,28 @@ static void
}
static void
+free_pending_req(PurpleDBusClientPendingRequest *req)
+{
+ g_closure_unref(req->close);
+ g_free(req);
+}
+
+static void
purple_dbus_callback_init(PurpleDBusCallback *self)
{
self->last_callback_id = 0;
self->callbacks = g_hash_table_new_full(g_int64_hash, g_int64_equal,
g_free, (GDestroyNotify)g_closure_unref);
- self->last_request_id = 0;
- self->requests = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)g_ptr_array_unref);
+ if (purple_core_is_daemon_mode()) {
+ self->last_request_id = 0;
+ self->requests = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, NULL,
+ (GDestroyNotify)g_ptr_array_unref);
+ }
+ if (purple_core_is_remote_mode())
+ self->client_reqs = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, NULL,
+ (GDestroyNotify)free_pending_req);
}
guint64
@@ -272,7 +289,7 @@ request_closed_cb(DBusGProxy *proxy, con
request_closed_cb(DBusGProxy *proxy, const guint request_id, gpointer data)
{
/* Forget about this pending request, execute the closing callback */
- purple_callback_run_request(request_id, 0);
+ purple_callback_close_client_req(request_id);
}
void
@@ -293,7 +310,7 @@ purple_dbus_callback_register(guint64 id
/**
* Registers a pending request.
- * @see purple_callback_register_req() or purple_callback_register_req_id().
+ * @see purple_callback_register_req().
*/
static void
purple_callback_add_req(guint request_id, guint n_closures, va_list ap)
@@ -333,12 +350,20 @@ void
}
void
-purple_callback_register_req_id(guint request_id, guint n_closures, ...)
+purple_callback_register_req_id(guint request_id, GClosure *close, void *handle)
{
- va_list ap;
- va_start(ap, n_closures);
- purple_callback_add_req(request_id, n_closures, ap);
- va_end(ap);
+ PurpleDBusCallback* handler = g_object_new(PURPLE_TYPE_DBUS_CALLBACK, NULL);
+ PurpleDBusClientPendingRequest *req;
+ void *key = GINT_TO_POINTER(request_id);
+
+ g_return_if_fail(handler != NULL);
+ g_return_if_fail(handler->client_reqs != NULL);
+
+ req = g_new0(PurpleDBusClientPendingRequest, 1);
+ req->close = close;
+ req->handle = handle;
+ req->request_id = request_id;
+ g_hash_table_insert(handler->client_reqs, key, req);
}
void
@@ -379,6 +404,8 @@ purple_callback_run_request(guint reques
closure = closures->pdata[choice];
/* Run it! */
+ purple_debug_info("dbus", "Answering request %u with choice %u\n",
+ request_id, choice);
g_closure_invoke(closure, NULL, 0, NULL, NULL);
/* If the request answer wasn't a close, this means the request
@@ -394,3 +421,49 @@ purple_callback_run_request(guint reques
g_hash_table_remove(handler->requests, key);
return TRUE;
}
+
+void
+purple_callback_close_client_req(guint request_id)
+{
+ PurpleDBusCallback* handler = g_object_new(PURPLE_TYPE_DBUS_CALLBACK, NULL);
+ PurpleDBusClientPendingRequest *req;
+ void *key = GINT_TO_POINTER(request_id);
+
+ g_return_if_fail(handler != NULL);
+ g_return_if_fail(handler->client_reqs != NULL);
+
+ /* Get the pending request back */
+ req = g_hash_table_lookup(handler->client_reqs, key);
+ if (!req)
+ return;
+
+ g_closure_invoke(req->close, NULL, 0, NULL, NULL);
+
+ /* Forget about this closed pending request */
+ g_hash_table_remove(handler->client_reqs, key);
+}
+
+/**
+ * Research function used by purple_callback_get_req_id().
+ */
+static gboolean
+find_ui_handle(guint key, PurpleDBusClientPendingRequest *req, void *ui_handle)
+{
+ return (req->handle == ui_handle);
+}
+
+guint
+purple_callback_get_req_id(void *ui_handle)
+{
+ PurpleDBusCallback* handler = g_object_new(PURPLE_TYPE_DBUS_CALLBACK, NULL);
+ PurpleDBusClientPendingRequest *req;
+
+ g_return_val_if_fail(handler != NULL, 0);
+ g_return_val_if_fail(handler->client_reqs != NULL, 0);
+
+ req = g_hash_table_find(handler->client_reqs,
+ (GHRFunc)find_ui_handle, ui_handle);
+ if (!req)
+ return 0;
+ return req->request_id;
+}
============================================================
--- libpurple/dbus-callback.h b4cbb0f81dcc35f70f866537f6fef24864063d2a
+++ libpurple/dbus-callback.h d4c1e33f673812ec72c5c93e27748aa78dc6b2d0
@@ -38,11 +38,23 @@ typedef struct {
} PurpleDBusCallbackClass;
typedef struct {
+ GClosure *close;
+ void *handle;
+ /* Request ids are already the keys for the client_reqs hash table,
+ * but we need them in the value too, for doing lookups of an id from
+ * a handle in purple_callback_get_req_id(). */
+ guint request_id;
+} PurpleDBusClientPendingRequest;
+
+typedef struct {
PurpleObject parent;
GHashTable *callbacks; /* id -> GClosure map */
guint64 last_callback_id;
+ /* This hash table is only used in daemon mode */
GHashTable *requests; /* id -> GPtrArray-of-GClosure map */
guint last_request_id;
+ /* This hash table is only used in remote mode */
+ GHashTable *client_reqs; /* id -> PurpleDBusClientPendingRequest */
} PurpleDBusCallback;
/* DBus transfered data formats */
@@ -90,16 +102,15 @@ guint purple_callback_register_req(guint
* Client version of purple_callback_register_req(), as it takes the
* daemon provided request id as parameter.
* The registered request can be later closed using the provided closing
- * closure, upon the reception of the CloseRequest dbus signal.
+ * closure, by the purple_callback_close_client_req() function.
*
- * @see purple_callback_register_req().
* @param request_id The request id.
- * @param n_closures The number of closures passed after this parameter
- * @param ... n_closures GClosures, each representing a choice that can answer
- * the request. The first choice must be the closing of the request,
- * and the others are the others available choices.
+ * @param close A closure that closes the request, its callback should take
+ * the handle as first parameter.
+ * @param handle The handle the UI returned for that request, e.g. the one
+ * returned by the request_authorize of PurpleAccountUiOps.
*/
-void purple_callback_register_req_id(guint request_id, guint n_closures, ...);
+void purple_callback_register_req_id(guint request_id, GClosure *close, void *handle);
/**
* Runs the choice choice of a pending request of id request_id.
@@ -122,5 +133,22 @@ gboolean DBUS_purple_callback_run_reques
*/
gboolean DBUS_purple_callback_run_request(PurpleDBusCallback *handler, guint request_id, guint choice, GError** error);
+/**
+ * Closes a pending client request, executing its closing closure provided
+ * in purple_callback_register_req_id().
+ *
+ * @param request_id The id of the request.
+ */
+void purple_callback_close_client_req(guint request_id);
+
+/**
+ * Used by a client to retrieve the request_id of a pending request.
+ *
+ * @param ui_handle The UI handle, e.g. as given to the close_account_request
+ * function of PurpleAccountUiOps.
+ * @return 0 if the ui_handle hasn't been found, or the request id if found.
+ */
+guint purple_callback_get_req_id(void *ui_handle);
+
#endif /* HAVE_DBUS */
#endif /* _DBUS_CALLBACK_H_ */
More information about the Commits
mailing list