[vala] D-Bus: Support no-reply methods in static libdbus clients
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] D-Bus: Support no-reply methods in static libdbus clients
- Date: Sun, 20 Jun 2010 10:46:40 +0000 (UTC)
commit 7514c9d7c19e91d304ce9de09e2831bb28ce0239
Author: Luca Bruno <lethalman88 gmail com>
Date: Sat May 29 16:12:20 2010 +0200
D-Bus: Support no-reply methods in static libdbus clients
Fixes bug 618892.
codegen/valadbusclientmodule.vala | 143 +++++++++++++++++++++++++++++++++++--
1 files changed, 138 insertions(+), 5 deletions(-)
---
diff --git a/codegen/valadbusclientmodule.vala b/codegen/valadbusclientmodule.vala
index f6e39ee..e047785 100644
--- a/codegen/valadbusclientmodule.vala
+++ b/codegen/valadbusclientmodule.vala
@@ -57,6 +57,17 @@ public class Vala.DBusClientModule : DBusModule {
return new CCodeConstant (timeout.to_string ());
}
+ public static bool is_dbus_no_reply (CodeNode node) {
+ var dbus_attribute = node.get_attribute ("DBus");
+ if (dbus_attribute != null
+ && dbus_attribute.has_argument ("no_reply")
+ && dbus_attribute.get_bool ("no_reply")) {
+ return true;
+ }
+
+ return false;
+ }
+
bool has_dbus_error (List<DataType> error_types) {
foreach (DataType error_type in error_types) {
if (((ErrorType) error_type).error_domain.get_full_name () == "DBus.Error") {
@@ -942,7 +953,12 @@ public class Vala.DBusClientModule : DBusModule {
foreach (Method m in iface.get_methods ()) {
var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), m.vfunc_name);
- if (!m.coroutine) {
+ if (is_dbus_no_reply (m)) {
+ if (m.coroutine) {
+ Report.error (m.source_reference, "No-reply DBus methods must not be async");
+ }
+ iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_noreply_dbus_proxy_method (main_iface, iface, m)))));
+ } else if (!m.coroutine) {
iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_method (main_iface, iface, m)))));
} else {
iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_async_dbus_proxy_method (main_iface, iface, m)))));
@@ -1629,6 +1645,8 @@ public class Vala.DBusClientModule : DBusModule {
void generate_marshalling (Method m, string dbus_iface_name, CCodeFragment prefragment, CCodeFragment postfragment) {
CCodeDeclaration cdecl;
+ var no_reply = is_dbus_no_reply (m);
+
var destination = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
destination.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*"));
var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path"));
@@ -1641,15 +1659,24 @@ public class Vala.DBusClientModule : DBusModule {
msgcall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m))));
prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), msgcall)));
+ if (no_reply) {
+ var noreplycall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_set_no_reply"));
+ noreplycall.add_argument (new CCodeIdentifier ("_message"));
+ noreplycall.add_argument (new CCodeConstant ("TRUE"));
+ prefragment.append (new CCodeExpressionStatement (noreplycall));
+ }
+
var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append"));
iter_call.add_argument (new CCodeIdentifier ("_message"));
iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter")));
prefragment.append (new CCodeExpressionStatement (iter_call));
- iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init"));
- iter_call.add_argument (new CCodeIdentifier ("_reply"));
- iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter")));
- postfragment.append (new CCodeExpressionStatement (iter_call));
+ if (!no_reply) {
+ iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init"));
+ iter_call.add_argument (new CCodeIdentifier ("_reply"));
+ iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter")));
+ postfragment.append (new CCodeExpressionStatement (iter_call));
+ }
foreach (FormalParameter param in m.get_parameters ()) {
if (param.direction == ParameterDirection.IN) {
@@ -1664,6 +1691,10 @@ public class Vala.DBusClientModule : DBusModule {
}
write_expression (prefragment, param.parameter_type, new CCodeIdentifier ("_iter"), expr);
} else {
+ if (no_reply) {
+ Report.error (param.source_reference, "No-reply DBus methods must not have out parameters");
+ break;
+ }
cdecl = new CCodeDeclaration (param.parameter_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator ("_" + param.name));
postfragment.append (cdecl);
@@ -1697,6 +1728,9 @@ public class Vala.DBusClientModule : DBusModule {
}
if (!(m.return_type is VoidType)) {
+ if (no_reply) {
+ Report.error (m.return_type.source_reference, "No-reply DBus methods must return void");
+ }
if (m.return_type.is_real_non_null_struct_type ()) {
var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
var expr = read_expression (postfragment, m.return_type, new CCodeIdentifier ("_iter"), target);
@@ -1736,6 +1770,10 @@ public class Vala.DBusClientModule : DBusModule {
Report.error (m.source_reference, "D-Bus methods must throw DBus.Error");
return;
}
+ if (is_dbus_no_reply (m)) {
+ // no-reply messages throw no error
+ return;
+ }
var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error"));
@@ -1882,6 +1920,101 @@ public class Vala.DBusClientModule : DBusModule {
return proxy_name;
}
+ string generate_noreply_dbus_proxy_method (Interface main_iface, Interface iface, Method m) {
+ string proxy_name = "%sdbus_proxy_%s".printf (main_iface.get_lower_case_cprefix (), m.name);
+
+ string dbus_iface_name = get_dbus_name (iface);
+
+ CCodeDeclaration cdecl;
+
+ var function = new CCodeFunction (proxy_name);
+ function.modifiers = CCodeModifiers.STATIC;
+
+ var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+ generate_cparameters (m, source_declarations, cparam_map, function);
+
+ var block = new CCodeBlock ();
+ var prefragment = new CCodeFragment ();
+ var postfragment = new CCodeFragment ();
+
+ // throw error and return if proxy is disposed
+ var dispose_return_block = new CCodeBlock ();
+ if (m.get_error_types ().size > 0) {
+ var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error"));
+ set_error_call.add_argument (new CCodeIdentifier ("error"));
+ set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR"));
+ set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_DISCONNECTED"));
+ set_error_call.add_argument (new CCodeConstant ("\"%s\""));
+ set_error_call.add_argument (new CCodeConstant ("\"Connection is closed\""));
+ dispose_return_block.add_statement (new CCodeExpressionStatement (set_error_call));
+ dispose_return_block.add_statement (new CCodeReturnStatement ());
+ }
+ block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), iface.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block));
+
+ cdecl = new CCodeDeclaration ("DBusGConnection");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection"));
+ block.add_statement (cdecl);
+
+ cdecl = new CCodeDeclaration ("DBusMessage");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("*_message"));
+ block.add_statement (cdecl);
+
+ cdecl = new CCodeDeclaration ("DBusMessageIter");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_iter"));
+ block.add_statement (cdecl);
+
+ block.add_statement (prefragment);
+
+ generate_marshalling (m, dbus_iface_name, prefragment, postfragment);
+
+ var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
+ gconnection.add_argument (new CCodeIdentifier ("self"));
+ gconnection.add_argument (new CCodeConstant ("\"connection\""));
+ gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection")));
+ gconnection.add_argument (new CCodeConstant ("NULL"));
+ block.add_statement (new CCodeExpressionStatement (gconnection));
+
+ var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection"));
+ connection.add_argument (new CCodeIdentifier ("_connection"));
+
+ var oom_return_block = new CCodeBlock ();
+ if (m.get_error_types ().size > 0) {
+ var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error"));
+ set_error_call.add_argument (new CCodeIdentifier ("error"));
+ set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR"));
+ set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_NO_MEMORY"));
+ set_error_call.add_argument (new CCodeConstant ("\"%s\""));
+ set_error_call.add_argument (new CCodeConstant ("\"Out of memory\""));
+ oom_return_block.add_statement (new CCodeExpressionStatement (set_error_call));
+ oom_return_block.add_statement (new CCodeReturnStatement ());
+ }
+
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send"));
+ ccall.add_argument (connection);
+ ccall.add_argument (new CCodeIdentifier ("_message"));
+ ccall.add_argument (new CCodeConstant ("NULL"));
+ block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, ccall), oom_return_block));
+
+ var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref"));
+ conn_unref.add_argument (new CCodeIdentifier ("_connection"));
+ block.add_statement (new CCodeExpressionStatement (conn_unref));
+
+ var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref"));
+ message_unref.add_argument (new CCodeIdentifier ("_message"));
+ block.add_statement (new CCodeExpressionStatement (message_unref));
+
+ check_error_reply (m, block);
+
+ block.add_statement (postfragment);
+
+ source_declarations.add_type_member_declaration (function.copy ());
+ function.block = block;
+ source_type_member_definition.append (function);
+
+ return proxy_name;
+ }
+
void generate_client_error_cases (CCodeBlock error_block, List<DataType> error_types, CCodeExpression dbus_error_name, CCodeExpression result_edomain, CCodeExpression result_ecode) {
CCodeStatement if_else_if = null;
CCodeIfStatement last_statement = null;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]