After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 623255 - valac generates broken C code for a _finish() function (GError** argument is missing)
valac generates broken C code for a _finish() function (GError** argument is ...
Status: RESOLVED FIXED
Product: vala
Classification: Core
Component: Async
0.9.x
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2010-07-01 02:16 UTC by Travis Reitter
Modified: 2010-07-08 20:35 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Travis Reitter 2010-07-01 02:16:58 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)
Comment 1 Jürg Billeter 2010-07-03 06:29:17 UTC
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.
Comment 2 Travis Reitter 2010-07-07 16:41:45 UTC
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.
Comment 3 Jürg Billeter 2010-07-08 20:35:01 UTC
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.