GNOME Bugzilla – Bug 623255
valac generates broken C code for a _finish() function (GError** argument is missing)
Last modified: 2010-07-08 20:35:01 UTC
I've got a class with an async function where the generated C code completely omits the final GError** argument in the corresponding _finish function (so gcc fails with an error). I'm using other async functions without a problem, and nothing about the vapi, etc. suggest any sort of problems. ================================ Vapi segment ================================ public class AccountManager : TelepathyGLib.Proxy { ... } [CCode (cname = "TpProxy", cheader_filename = "telepathy-glib/telepathy-glib.h")] public class Proxy : GLib.Object { public weak GLib.Object parent; public TelepathyGLib.ProxyPrivate priv; ... public async void prepare_async ([CCode (array_length = false)] GLib.Quark[]? features); public bool prepare_finish (GLib.AsyncResult result) throws GLib.Error; } ================================ Vala segment ================================ private async void setup_account_manager () { this.account_manager = AccountManager.dup (); try { yield this.account_manager.prepare_async (null); } catch (GLib.Error e) { warning ("failed to prepare account manager: %s", e.message); } ... } ================================ generated C code ================================ struct _FolksBackendsTpBackendSetupAccountManagerData { int _state_; GAsyncResult* _res_; GSimpleAsyncResult* _async_result; FolksBackendsTpBackend* self; TpAccountManager* _tmp0_; GError * e; GList* accounts; GList* account_collection; GList* account_it; TpAccount* account; GError * _inner_error_; }; ... _state_0: { data->self->priv->account_manager = (data->_tmp0_ = tp_account_manager_dup (), _g_object_unref0 (data->self->priv->account_manager), data->_tmp0_); { data->_state_ = 1; tp_proxy_prepare_async ((TpProxy*) data->self->priv->account_manager, NULL, folks_backends_tp_backend_setup_account_manager_ready, data); return FALSE; _state_1: tp_proxy_prepare_finish ((TpProxy*) data->self->priv->account_manager, data->_res_); } goto __finally0; __catch0_g_error: { data->e = data->_inner_error_; data->_inner_error_ = NULL; { g_warning ("tp-backend.vala:57: failed to prepare account manager: %s", data->e->message); _g_error_free0 (data->e); } } __finally0: if (data->_inner_error_ != NULL) { g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, data->_inner_error_->message, g_quark_to_string (data->_inner_error_->domain), data->_inner_error_->code); g_clear_error (&data->_inner_error_); return FALSE; } ================================= Note the tp_proxy_prepare_finish() line above is missing the GError ** argument entirely (causing a compiler error); yet all the other references to data->_inner_error_ seem as they should be. ================================= This blocks the Vala bindings for telepathy glib (fdo #27792)
The vapi should look like this: public async bool prepare_async ([CCode (array_length = false)] GLib.Quark[]? features) throws GLib.Error; The _finish function should not be bound separately.
The decision we came to here was to add vala-gen-introspect's heuristic for turning _async/_finish GAsyncResult(Callback) pairs to vapigen. Simultaneously, bug #623635 should add more annotations to GIR files for async functions. Once that's fixed, we should be able to simplify the code in vapigen to just parse those.
commit cb4601c7339a4d4aa3079b74e6fbd467c3779268 Author: Jürg Billeter <j@bitron.ch> Date: Thu Jul 8 21:57:31 2010 +0200 girparser: Handle asynchronous methods Fixes bug 623255.