[vala] D-Bus: Support no-reply methods in GDBus clients and servers



commit b45145d25b661807f33c792d57fd2711dcc806bc
Author: Jürg Billeter <j bitron ch>
Date:   Fri Oct 8 00:23:03 2010 +0200

    D-Bus: Support no-reply methods in GDBus clients and servers
    
    Fixes bug 618892.

 codegen/valagdbusclientmodule.vala |  114 ++++++++++++++++++++++++++----------
 codegen/valagdbusmodule.vala       |   11 ++++
 codegen/valagdbusservermodule.vala |   40 ++++++++-----
 3 files changed, 120 insertions(+), 45 deletions(-)
---
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 4ce19b4..a1ebeb4 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -422,7 +422,7 @@ public class Vala.GDBusClientModule : GDBusModule {
 		cfile.add_function (cfunc);
 	}
 
-	void generate_marshalling (Method m, CCodeFragment prefragment, CCodeFragment postfragment) {
+	void generate_marshalling (Method m, CCodeFragment prefragment, CCodeFragment postfragment, bool no_reply = false) {
 		CCodeDeclaration cdecl;
 
 		cdecl = new CCodeDeclaration ("GVariantBuilder");
@@ -434,14 +434,16 @@ public class Vala.GDBusClientModule : GDBusModule {
 		builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
 		prefragment.append (new CCodeExpressionStatement (builder_init));
 
-		cdecl = new CCodeDeclaration ("GVariantIter");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_iter"));
-		postfragment.append (cdecl);
+		if (!no_reply) {
+			cdecl = new CCodeDeclaration ("GVariantIter");
+			cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_iter"));
+			postfragment.append (cdecl);
 
-		var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
-		iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_iter")));
-		iter_init.add_argument (new CCodeIdentifier ("_reply"));
-		postfragment.append (new CCodeExpressionStatement (iter_init));
+			var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
+			iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_iter")));
+			iter_init.add_argument (new CCodeIdentifier ("_reply"));
+			postfragment.append (new CCodeExpressionStatement (iter_init));
+		}
 
 		foreach (FormalParameter param in m.get_parameters ()) {
 			if (param.direction == ParameterDirection.IN) {
@@ -521,6 +523,8 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		string dbus_iface_name = get_dbus_name (iface);
 
+		bool no_reply = is_dbus_no_reply (m);
+
 		CCodeDeclaration cdecl;
 
 		var function = new CCodeFunction (proxy_name);
@@ -536,40 +540,88 @@ public class Vala.GDBusClientModule : GDBusModule {
 
 		cdecl = new CCodeDeclaration ("GVariant");
 		cdecl.add_declarator (new CCodeVariableDeclarator ("*_arguments"));
-		cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
+		if (!no_reply) {
+			cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
+		}
 		block.add_statement (cdecl);
 
-		generate_marshalling (m, prefragment, postfragment);
+		generate_marshalling (m, prefragment, postfragment, no_reply);
 
 		block.add_statement (prefragment);
 
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
-		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
-		ccall.add_argument (new CCodeConstant ("\"%s.%s\"".printf (dbus_iface_name, get_dbus_name_for_member (m))));
-		ccall.add_argument (new CCodeIdentifier ("_arguments"));
-		ccall.add_argument (new CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
-		ccall.add_argument (get_dbus_timeout (m));
-		ccall.add_argument (new CCodeConstant ("NULL"));
-		ccall.add_argument (new CCodeConstant ("error"));
-		block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
-
-		// return on error
-		var error_block = new CCodeBlock ();
-		if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) {
-			error_block.add_statement (new CCodeReturnStatement ());
+		if (no_reply) {
+			cdecl = new CCodeDeclaration ("GDBusMessage");
+			cdecl.add_declarator (new CCodeVariableDeclarator ("*_message"));
+			block.add_statement (cdecl);
+
+			var connection = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_connection"));
+			connection.add_argument (new CCodeIdentifier ("self"));
+
+			var destination = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_name"));
+			destination.add_argument (new CCodeIdentifier ("self"));
+
+			var object_path = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_object_path"));
+			object_path.add_argument (new CCodeIdentifier ("self"));
+
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_new_method_call"));
+			ccall.add_argument (destination);
+			ccall.add_argument (object_path);
+			ccall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name)));
+			ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m))));
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), ccall)));
+
+			var set_flags = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_flags"));
+			set_flags.add_argument (new CCodeIdentifier ("_message"));
+			set_flags.add_argument (new CCodeConstant ("G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED"));
+			block.add_statement (new CCodeExpressionStatement (set_flags));
+
+			var set_body = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_body"));
+			set_body.add_argument (new CCodeIdentifier ("_message"));
+			set_body.add_argument (new CCodeIdentifier ("_arguments"));
+			block.add_statement (new CCodeExpressionStatement (set_body));
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message"));
+			ccall.add_argument (connection);
+			ccall.add_argument (new CCodeIdentifier ("_message"));
+			ccall.add_argument (new CCodeConstant ("0"));
+			ccall.add_argument (new CCodeConstant ("NULL"));
+			ccall.add_argument (new CCodeIdentifier ("error"));
+			block.add_statement (new CCodeExpressionStatement (ccall));
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+			ccall.add_argument (new CCodeIdentifier ("_message"));
+			block.add_statement (new CCodeExpressionStatement (ccall));
 		} else {
-			error_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false)));
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
+			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
+			ccall.add_argument (new CCodeConstant ("\"%s.%s\"".printf (dbus_iface_name, get_dbus_name_for_member (m))));
+			ccall.add_argument (new CCodeIdentifier ("_arguments"));
+			ccall.add_argument (new CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
+			ccall.add_argument (get_dbus_timeout (m));
+			ccall.add_argument (new CCodeConstant ("NULL"));
+			ccall.add_argument (new CCodeIdentifier ("error"));
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
+
+			// return on error
+			var error_block = new CCodeBlock ();
+			if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) {
+				error_block.add_statement (new CCodeReturnStatement ());
+			} else {
+				error_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false)));
+			}
+			block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")), error_block));
 		}
-		block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")), error_block));
 
 		block.add_statement (postfragment);
 
-		var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
-		unref_reply.add_argument (new CCodeIdentifier ("_reply"));
-		block.add_statement (new CCodeExpressionStatement (unref_reply));
+		if (!no_reply) {
+			var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
+			unref_reply.add_argument (new CCodeIdentifier ("_reply"));
+			block.add_statement (new CCodeExpressionStatement (unref_reply));
 
-		if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ())) {
-			block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+			if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ())) {
+				block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+			}
 		}
 
 		cfile.add_function_declaration (function);
diff --git a/codegen/valagdbusmodule.vala b/codegen/valagdbusmodule.vala
index 55aece2..94bf928 100644
--- a/codegen/valagdbusmodule.vala
+++ b/codegen/valagdbusmodule.vala
@@ -39,6 +39,17 @@ public class Vala.GDBusModule : GVariantModule {
 		return Symbol.lower_case_to_camel_case (symbol.name);
 	}
 
+	public static bool is_dbus_no_reply (Method m) {
+		var dbus_attribute = m.get_attribute ("DBus");
+		if (dbus_attribute != null
+		    && dbus_attribute.has_argument ("no_reply")
+		    && dbus_attribute.get_bool ("no_reply")) {
+			return true;
+		}
+
+		return false;
+	}
+
 	public override void visit_error_domain (ErrorDomain edomain) {
 		var edomain_dbus_name = get_dbus_name (edomain);
 		if (edomain_dbus_name == null) {
diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala
index c94043c..01f7fa2 100644
--- a/codegen/valagdbusservermodule.vala
+++ b/codegen/valagdbusservermodule.vala
@@ -77,6 +77,8 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 			ready_block.add_statement (cdecl);
 		}
 
+		bool no_reply = is_dbus_no_reply (m);
+
 		var in_prefragment = new CCodeFragment ();
 		var in_postfragment = new CCodeFragment ();
 		var out_prefragment = in_prefragment;
@@ -99,9 +101,11 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 			ready_block.add_statement (out_prefragment);
 		}
 
-		cdecl = new CCodeDeclaration ("GVariant*");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_reply"));
-		out_postfragment.append (cdecl);
+		if (!no_reply) {
+			cdecl = new CCodeDeclaration ("GVariant*");
+			cdecl.add_declarator (new CCodeVariableDeclarator ("_reply"));
+			out_postfragment.append (cdecl);
+		}
 
 		cdecl = new CCodeDeclaration ("GVariantIter");
 		cdecl.add_declarator (new CCodeVariableDeclarator ("_arguments_iter"));
@@ -112,14 +116,16 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		iter_init.add_argument (new CCodeIdentifier ("parameters"));
 		in_prefragment.append (new CCodeExpressionStatement (iter_init));
 
-		cdecl = new CCodeDeclaration ("GVariantBuilder");
-		cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_builder"));
-		out_postfragment.append (cdecl);
+		if (!no_reply) {
+			cdecl = new CCodeDeclaration ("GVariantBuilder");
+			cdecl.add_declarator (new CCodeVariableDeclarator ("_reply_builder"));
+			out_postfragment.append (cdecl);
 
-		var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
-		builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
-		builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
-		out_postfragment.append (new CCodeExpressionStatement (builder_init));
+			var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
+			builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
+			builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
+			out_postfragment.append (new CCodeExpressionStatement (builder_init));
+		}
 
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
 
@@ -274,9 +280,11 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 			}
 		}
 
-		var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
-		builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
-		out_postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), builder_end)));
+		if (!no_reply) {
+			var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
+			builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
+			out_postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), builder_end)));
+		}
 
 		if (m.coroutine) {
 			ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (wrapper_name + "_ready"), "GAsyncReadyCallback"));
@@ -312,7 +320,11 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 
 		block.add_statement (in_postfragment);
 
-		if (!m.coroutine) {
+		if (no_reply) {
+			var return_value = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+			return_value.add_argument (new CCodeIdentifier ("invocation"));
+			block.add_statement (new CCodeExpressionStatement (return_value));
+		} else if (!m.coroutine) {
 			var return_value = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_value"));
 			return_value.add_argument (new CCodeIdentifier ("invocation"));
 			return_value.add_argument (new CCodeIdentifier ("_reply"));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]