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