From: Jürg Billeter Date: Wed, 20 Oct 2010 21:15:01 +0000 (+0200) Subject: D-Bus: Add async Bus.get_proxy method for GDBus clients X-Git-Tag: 0.11.1~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=918d7d22a25f0ccc0f9b22000cc778c0fed2b8f2;p=thirdparty%2Fvala.git D-Bus: Add async Bus.get_proxy method for GDBus clients Fixes bug 622611. --- diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index 8147358bd..fc5a64d50 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -28,6 +28,7 @@ public class Vala.GAsyncModule : GSignalModule { var data = new CCodeStruct ("_" + dataname); data.add_field ("int", "_state_"); + data.add_field ("GObject*", "_source_object_"); data.add_field ("GAsyncResult*", "_res_"); data.add_field ("GSimpleAsyncResult*", "_async_result"); @@ -498,6 +499,7 @@ public class Vala.GAsyncModule : GSignalModule { datadecl.add_declarator (new CCodeVariableDeclarator ("data")); readyblock.add_statement (datadecl); readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), new CCodeIdentifier ("_user_data_")))); + readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_source_object_"), new CCodeIdentifier ("source_object")))); readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_res_"), new CCodeIdentifier ("_res_")))); var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co")); diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala index 42d3e12c7..120fe2482 100644 --- a/codegen/valagdbusclientmodule.vala +++ b/codegen/valagdbusclientmodule.vala @@ -198,9 +198,11 @@ public class Vala.GDBusClientModule : GDBusModule { public override void visit_method_call (MethodCall expr) { var mtype = expr.call.value_type as MethodType; + bool bus_get_proxy_async = (mtype != null && mtype.method_symbol.get_cname () == "g_bus_get_proxy"); bool bus_get_proxy_sync = (mtype != null && mtype.method_symbol.get_cname () == "g_bus_get_proxy_sync"); + bool conn_get_proxy_async = (mtype != null && mtype.method_symbol.get_cname () == "g_dbus_connection_get_proxy_sync"); bool conn_get_proxy_sync = (mtype != null && mtype.method_symbol.get_cname () == "g_dbus_connection_get_proxy_sync"); - if (!bus_get_proxy_sync && !conn_get_proxy_sync) { + if (!bus_get_proxy_async && !bus_get_proxy_sync && !conn_get_proxy_async && !conn_get_proxy_sync) { base.visit_method_call (expr); return; } @@ -216,7 +218,7 @@ public class Vala.GDBusClientModule : GDBusModule { } var base_arg_index = 0; - if (bus_get_proxy_sync) + if (bus_get_proxy_async || bus_get_proxy_sync) base_arg_index = 1; var args = expr.get_argument_list (); @@ -228,17 +230,34 @@ public class Vala.GDBusClientModule : GDBusModule { // method can fail current_method_inner_error = true; - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_initable_new")); + CCodeFunctionCall ccall; + if (bus_get_proxy_async || conn_get_proxy_async) { + ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_async_initable_new_async")); + } else { + ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_initable_new")); + } ccall.add_argument (new CCodeIdentifier ("%s_PROXY".printf (iface.get_type_id ()))); + if (bus_get_proxy_async || conn_get_proxy_async) { + // I/O priority + ccall.add_argument (new CCodeConstant ("0")); + } cancellable.emit (this); ccall.add_argument (get_cvalue (cancellable)); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_"))); + if (bus_get_proxy_async || conn_get_proxy_async) { + if (expr.is_yield_expression) { + // asynchronous call + ccall.add_argument (new CCodeIdentifier (current_method.get_cname () + "_ready")); + ccall.add_argument (new CCodeIdentifier ("data")); + } + } else { + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_"))); + } ccall.add_argument (new CCodeConstant ("\"g-flags\"")); ccall.add_argument (get_cvalue (flags)); ccall.add_argument (new CCodeConstant ("\"g-name\"")); name.emit (this); ccall.add_argument (get_cvalue (name)); - if (bus_get_proxy_sync) { + if (bus_get_proxy_async || bus_get_proxy_sync) { Expression bus_type = args.get (0); ccall.add_argument (new CCodeConstant ("\"g-bus-type\"")); bus_type.emit (this); @@ -255,6 +274,24 @@ public class Vala.GDBusClientModule : GDBusModule { ccall.add_argument (new CCodeConstant ("\"g-interface-name\"")); ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name (iface)))); ccall.add_argument (new CCodeConstant ("NULL")); + + if (bus_get_proxy_async || conn_get_proxy_async) { + if (expr.is_yield_expression) { + int state = next_coroutine_state++; + + ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ()))); + ccode.add_expression (ccall); + ccode.add_return (new CCodeConstant ("FALSE")); + ccode.add_label ("_state_%d".printf (state)); + + ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_async_initable_new_finish")); + ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_source_object_")); + // pass GAsyncResult stored in closure to finish function + ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_res_")); + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_"))); + } + } + set_cvalue (expr, ccall); } diff --git a/tests/dbus/async-errors.test b/tests/dbus/async-errors.test index 7dd3edbbb..c3c669f54 100644 --- a/tests/dbus/async-errors.test +++ b/tests/dbus/async-errors.test @@ -12,7 +12,9 @@ interface Test : Object { MainLoop main_loop; -async void run (Test test) { +async void run () { + Test test = yield Bus.get_proxy (BusType.SESSION, "org.example.Test", "/org/example/test"); + try { yield test.test_void (); assert_not_reached (); @@ -38,9 +40,7 @@ async void run (Test test) { void main () { // client - Test test = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/test"); - - run.begin (test); + run.begin (); main_loop = new MainLoop (null, false); main_loop.run (); diff --git a/tests/dbus/async.test b/tests/dbus/async.test index 7aa736317..cb6a541fc 100644 --- a/tests/dbus/async.test +++ b/tests/dbus/async.test @@ -12,7 +12,9 @@ interface Test : Object { MainLoop main_loop; -async void run (Test test) { +async void run () { + Test test = yield Bus.get_proxy (BusType.SESSION, "org.example.Test", "/org/example/test"); + yield test.test_void (); int j, k; @@ -30,9 +32,7 @@ async void run (Test test) { void main () { // client - Test test = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/test"); - - run.begin (test); + run.begin (); main_loop = new MainLoop (null, false); main_loop.run (); diff --git a/vapi/gio-2.0.vapi b/vapi/gio-2.0.vapi index 8283164e5..542e8ef74 100644 --- a/vapi/gio-2.0.vapi +++ b/vapi/gio-2.0.vapi @@ -7,6 +7,8 @@ namespace GLib { [CCode (cheader_filename = "gio/gio.h")] public static async GLib.DBusConnection @get (GLib.BusType bus_type, GLib.Cancellable? cancellable = null) throws GLib.IOError; [CCode (cheader_filename = "gio/gio.h")] + public static async T get_proxy (GLib.BusType bus_type, string name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; + [CCode (cheader_filename = "gio/gio.h")] public static T get_proxy_sync (GLib.BusType bus_type, string name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; [CCode (cheader_filename = "gio/gio.h")] public static GLib.DBusConnection get_sync (GLib.BusType bus_type, GLib.Cancellable? cancellable = null) throws GLib.IOError; @@ -200,6 +202,7 @@ namespace GLib { public bool get_exit_on_close (); public unowned string get_guid (); public unowned GLib.Credentials get_peer_credentials (); + public async T get_proxy (string? name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; public T get_proxy_sync (string? name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; public unowned GLib.IOStream get_stream (); public unowned string get_unique_name (); diff --git a/vapi/packages/gio-2.0/gio-2.0-custom.vala b/vapi/packages/gio-2.0/gio-2.0-custom.vala index ed214fe68..ad3be523f 100644 --- a/vapi/packages/gio-2.0/gio-2.0-custom.vala +++ b/vapi/packages/gio-2.0/gio-2.0-custom.vala @@ -56,6 +56,7 @@ namespace GLib { namespace Bus { public async GLib.DBusConnection get (GLib.BusType bus_type, GLib.Cancellable? cancellable = null) throws GLib.IOError; public GLib.DBusConnection get_sync (GLib.BusType bus_type, GLib.Cancellable? cancellable = null) throws GLib.IOError; + public async T get_proxy (GLib.BusType bus_type, string name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; public T get_proxy_sync (GLib.BusType bus_type, string name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; [CCode (cname = "g_bus_own_name_with_closures")] public uint own_name (GLib.BusType bus_type, string name, GLib.BusNameOwnerFlags flags, [CCode (type = "GClosure*")] owned GLib.BusAcquiredCallback bus_acquired_handler, [CCode (type = "GClosure*")] owned GLib.BusNameAcquiredCallback name_acquired_handler, [CCode (type = "GClosure*")] owned GLib.BusNameLostCallback name_lost_handler); @@ -71,6 +72,7 @@ namespace GLib { [CCode (cname = "GDBusConnection")] public class DBusConnection { + public async T get_proxy (string? name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; public T get_proxy_sync (string? name, string object_path, GLib.DBusProxyFlags flags = 0, GLib.Cancellable? cancellable = null) throws GLib.IOError; public uint register_object (string object_path, T object) throws GLib.IOError; }