soc.2010.detachablepurple: 8b83309a: Modified purple_callback_register_req(), ...

gillux at soc.pidgin.im gillux at soc.pidgin.im
Sat Jul 31 01:35:55 EDT 2010


----------------------------------------------------------------------
Revision: 8b83309a890ff2e1f79593c4cda35337bda94a51
Parent:   59851f3cb683e9172dce6c8b90c5079f9b543d78
Author:   gillux at soc.pidgin.im
Date:     07/30/10 19:06:35
Branch:   im.pidgin.soc.2010.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/8b83309a890ff2e1f79593c4cda35337bda94a51

Changelog: 

Modified purple_callback_register_req(), caller must now provide a callback that
closes the request as first closure. Thus the RunRequest dbus method can either
close a request if we give the choice 0, or execute another choice > 0 and then
automatically close the request executing choice 0. This way, all the others
clients would close their local pending request if one of them handled it,
whether it's with a close or another choice.

Also added purple_callback_register_req_id(), which basically do the same but
aims to be used on the client side, requiering the request id as first arg
instead of generating it. This way, both daemon and clients are able to register
a request with a close callback so the closing can be automatically handled,
giving the request id.

Changes against parent 59851f3cb683e9172dce6c8b90c5079f9b543d78

  patched  libpurple/account-dbus.c
  patched  libpurple/dbus-callback.c
  patched  libpurple/dbus-callback.h

-------------- next part --------------
============================================================
--- libpurple/account-dbus.c	ea6719cd5930a846ebe3fb29baec9f592905565a
+++ libpurple/account-dbus.c	2b3bd88b46773c3376270cc2f62f8f343d42febe
@@ -11,6 +11,7 @@
 #include "dbus-constructor-client.h"
 #include "dbus-maybe.h"
 #include "marshallers.h"
+#include "nullmarshaller.h"
 
 /**
  * Callback, called when we receive a dbus "NotifyAdded" signal.
@@ -39,27 +40,27 @@ request_add_cb(DBusGProxy *proxy, const 
 /**
  * Callback called on the client when the user accepted an auth request.
  * It runs the RunRequest method on the daemon, with the original request id,
- * and the request choice number 0 (authorized).
+ * and the request choice number 1 (authorized).
  */
 static void
 request_remote_client_auth_cb(void *user_data)
 {
 	guint request_id = GPOINTER_TO_INT(user_data);
 	g_return_if_fail(request_id != 0);
-	purple_callback_run_request_RPC(request_id, 0);
+	purple_callback_run_request_RPC(request_id, 1);
 }
 
 /**
  * Callback called on the client when the user denied an auth request.
  * It runs the RunRequest method on the daemon, with the original request id,
- * and the request choice number 1 (denied).
+ * and the request choice number 2 (denied).
  */
 static void
 request_remote_client_deny_cb(void *user_data)
 {
 	guint request_id = GPOINTER_TO_INT(user_data);
 	g_return_if_fail(request_id != 0);
-	purple_callback_run_request_RPC(request_id, 1);
+	purple_callback_run_request_RPC(request_id, 2);
 }
 
 /**
@@ -70,6 +71,7 @@ request_authorize_cb(DBusGProxy *proxy, 
                      const char *id,    const char *alias, const char *message,
                      gboolean on_list,  guint request_id,  gpointer data)
 {
+	GClosure *close_req;
 	void *h;
 	PurpleAccount* account = PURPLE_ACCOUNT(
                 purple_dbus_get_gobject_by_path(dbus_g_proxy_get_path(proxy)));
@@ -83,6 +85,21 @@ request_authorize_cb(DBusGProxy *proxy, 
                                                  request_remote_client_auth_cb,
                                                  request_remote_client_deny_cb,
                                                  GINT_TO_POINTER(request_id));
+
+        /* Note that not getting a handle back here means the request
+         * has been already handled synchronously, so there is no need
+         * to register the request */
+        if (h) {
+	        /* Register a closure to close this pending request, so that
+	         * if the daemon tells us this request has been handled
+	         * (with the RequestClosed dbus signal), then it will be
+	         * automatically and properly closed */
+	        close_req = g_cclosure_new(
+	                             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);
+        }
 }
 
 static char*
============================================================
--- libpurple/dbus-callback.c	9389b8caedb1d336ec78ae21ec61f9e51c190c69
+++ libpurple/dbus-callback.c	221b20bd6693435274e288335fa022c6286c8a50
@@ -268,34 +268,57 @@ purple_dbus_callback_register(guint64 id
 	g_hash_table_insert(handler->callbacks, new_id, closure);
 }
 
-guint
-purple_callback_register_req(guint n_closures, ...)
+/**
+ * Registers a pending request.
+ * @see purple_callback_register_req() or purple_callback_register_req_id().
+ */
+static void
+purple_callback_add_req(guint request_id, guint n_closures, va_list ap)
 {
 	PurpleDBusCallback* handler = g_object_new(PURPLE_TYPE_DBUS_CALLBACK, NULL);
-	va_list ap;
 	GPtrArray *closures;
 	int i;
 	void *key;
 
-	g_return_val_if_fail(handler != NULL, 0);
-	g_return_val_if_fail(handler->requests != NULL, 0);
+	g_return_if_fail(handler != NULL);
+	g_return_if_fail(handler->requests != NULL);
 
 	/* Put the provided closures in a GPtrArray */
 	closures = g_ptr_array_sized_new(n_closures);
 	g_ptr_array_set_free_func(closures, (GDestroyNotify)g_closure_unref);
-	va_start(ap, n_closures);
 	for (i = 0; i < n_closures; i++)
 		g_ptr_array_add(closures, va_arg(ap, GClosure *));
-	va_end(ap);
 
 	/* Put the array in our hash table */
-	key = GINT_TO_POINTER(++handler->last_request_id);
+	key = GINT_TO_POINTER(request_id);
 	g_hash_table_insert(handler->requests, key, closures);
+}
 
+guint
+purple_callback_register_req(guint n_closures, ...)
+{
+	PurpleDBusCallback* handler = g_object_new(PURPLE_TYPE_DBUS_CALLBACK, NULL);
+	va_list ap;
+
+	g_return_val_if_fail(handler != NULL, 0);
+	g_return_val_if_fail(handler->requests != NULL, 0);
+
+	va_start(ap, n_closures);
+	purple_callback_add_req(++handler->last_request_id, n_closures, ap);
+	va_end(ap);
 	return handler->last_request_id;
 }
 
 void
+purple_callback_register_req_id(guint request_id, guint n_closures, ...)
+{
+	va_list ap;
+	va_start(ap, n_closures);
+	purple_callback_add_req(request_id, n_closures, ap);
+	va_end(ap);
+}
+
+void
 purple_callback_run_request_RPC(guint request_id, guint choice)
 {
 	PurpleDBusCallback* handler = g_object_new(PURPLE_TYPE_DBUS_CALLBACK, NULL);
@@ -328,6 +351,15 @@ DBUS_purple_callback_run_request(PurpleD
 	/* Run it! */
 	g_closure_invoke(closure, NULL, 0, NULL, NULL);
 
+	/* If the request answer wasn't a close, this means the request
+	 * has been handled, so we need to inform the other clients they
+	 * have to close it now. */
+	if (choice > 0) {
+		closure = closures->pdata[0];
+		if (closure)
+			g_closure_invoke(closure, NULL, 0, NULL, NULL);
+	}
+
 	/* Forget about this pending request, it has been handled */
 	g_hash_table_remove(handler->requests, key);
 	return TRUE;
============================================================
--- libpurple/dbus-callback.h	b592df26ea5e69c379a11ff63c34db0767b28363
+++ libpurple/dbus-callback.h	93f6bdf2733dc9b83f71daf98125d3e9b9b80a4b
@@ -70,12 +70,14 @@ void purple_dbus_callback__b(void *obj, 
 
 /**
  * Register a pending request, with n_closures available choices.
+ * Used on daemon side, as it generates a new unique id.
  * The request can be later answered by one of the choices available choices,
  * using the dbus RunRequest method with the returned 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 request. The first choice must be the closing of the request,
+ *            and the others are the others available choices.
  * @return A request id that identifies the created pending request. This id
  *         can be passed to the dbus RunRequest method, which can be called
  *         on the client side with purple_dbus_callback_run_request_RPC().
@@ -83,6 +85,21 @@ guint purple_callback_register_req(guint
 guint purple_callback_register_req(guint n_closures, ...);
 
 /**
+ * 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.
+ * 
+ * @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.
+ */
+void purple_callback_register_req_id(guint request_id, guint n_closures, ...);
+
+/**
  * Client side function that run the RunRequest dbus method on the daemon.
  */
 void purple_callback_run_request_RPC(guint request_id, guint choice);


More information about the Commits mailing list