]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
D-Bus: Support no-reply methods in GDBus clients and servers
authorJürg Billeter <j@bitron.ch>
Thu, 7 Oct 2010 22:23:03 +0000 (00:23 +0200)
committerJürg Billeter <j@bitron.ch>
Thu, 7 Oct 2010 22:38:00 +0000 (00:38 +0200)
Fixes bug 618892.

codegen/valagdbusclientmodule.vala
codegen/valagdbusmodule.vala
codegen/valagdbusservermodule.vala

index 4ce19b490195e4ad9d01de689bcc77ffedd83270..a1ebeb42569e06263d93257f6d59e9355d65e32e 100644 (file)
@@ -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);
index 55aece233dffcdb89e5596b2b41e1d91a2c708fc..94bf9283d3fa869a5394faf8aed292684545823a 100644 (file)
@@ -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) {
index c94043c81353831bad77ffc883f3eede4d608e55..01f7fa2a59ee680db44c9f836f35297ef80aaab3 100644 (file)
@@ -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"));