GNOME Bugzilla – Bug 741485
Captured variable struct missing ref
Last modified: 2014-12-17 19:34:10 UTC
Created attachment 292668 [details] Code that shows the problem It seems that the data structure setup to capture variables for callbacks gets created with a reference count of one, but then unref'd in the same function. Meaning it gets deallocated before the callback can get called. I've attached a small bit of Vala code that shows this with the Pulse interface (where I found it), but I think that it happens with all callbacks used with captured variables that don't have a a destroy callback. For instance I also have an callback with timeout which adds an additional ref in the C code. Here's the offending generated function: void dopulse (const gchar* printout) { Block1Data* _data1_; const gchar* _tmp0_ = NULL; gchar* _tmp1_ = NULL; pa_glib_mainloop* loop = NULL; pa_glib_mainloop* _tmp2_ = NULL; pa_proplist* props = NULL; pa_proplist* _tmp3_ = NULL; pa_context* context = NULL; pa_mainloop_api* _tmp4_ = NULL; pa_context* _tmp5_ = NULL; pa_operation* _tmp6_ = NULL; pa_operation* _tmp7_ = NULL; g_return_if_fail (printout != NULL); _data1_ = g_slice_new0 (Block1Data); _data1_->_ref_count_ = 1; _tmp0_ = printout; _tmp1_ = g_strdup (_tmp0_); _g_free0 (_data1_->printout); _data1_->printout = _tmp1_; _tmp2_ = pa_glib_mainloop_new (NULL); loop = _tmp2_; _tmp3_ = pa_proplist_new (); props = _tmp3_; _tmp4_ = pa_glib_mainloop_get_api (loop); _tmp5_ = pa_context_new_with_proplist (_tmp4_, NULL, props); context = _tmp5_; _tmp6_ = pa_context_get_server_info (context, ___lambda4__pa_context_serverinfocb, _data1_); _tmp7_ = _tmp6_; _pa_operation_unref0 (_tmp7_); _pa_context_unref0 (context); _pa_proplist_free0 (props); _pa_glib_mainloop_free0 (loop); block1_data_unref (_data1_); _data1_ = NULL; } There needs to be an additional call to block1_data_ref() or remove the block1_data_unref() call.
This is a problem of the pulseaudio bindings. What bindings are you using? We do not ship pulseaudio bindings.
Pulse ships their own VAPI file. I don't see any issue with it: http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/vala/libpulse.vapi#n1039
The parameter should probably have [CCode (scope = "async")]
I added that to the VAPI file and regenerated the attached Vala file and the issue is not fixed.
If it doesn't add a further ref of the block then you are using an old valac version.
Sorry, also add the "owned" keyword.
I used the owned keyword and that didn't change the generation of the C file for me. I'm using valac 0.26.1.
Oh, I also tried in Valac 0.24 and the bug also occurs in that version of the compiler. It seems to be a long standing bug.
I've changed the libpulse.vapi to: public Operation? get_server_info([CCode (scope = "async")] owned ServerInfoCb cb); And I get: _tmp6_ = pa_context_get_server_info (context, ___lambda4__pa_context_serverinfocb, block1_data_ref (_data1_)); Perhaps you aren't referring to your own modified libpulse.vapi correctly.
Closing. It's ok from Vala. The pulseaudio bindings need a fix. Please reopen if needed.