Gnome bugzilla is down today, so after the deafening silence on IRC I figured I might give mail a chance. This function:
======================================================================== public override async void play_sound( string name, int loop, int length ) throws FreeSmartphone.Device.AudioError, FreeSmartphone.Error { PlayingSound sound = sounds[name]; if ( sound != null ) { throw new FreeSmartphone.Device.AudioError.ALREADY_PLAYING( "%s is already playing".printf( name ) ); } var parts = name.split( "." ); if ( parts.length == 0 ) { throw new FreeSmartphone.Error.INVALID_PARAMETER( "Could not guess media format; need an extension" ); } var extension = parts[ parts.length - 1 ]; // darn, I miss negative array indices var decoder = decoders[extension]; assert( decoder != null ); assert( this != null ); try ERROR:plugin.c:464:_lambda1_: assertion failed: (self != NULL) Aborted { var pipeline = Gst.parse_launch( @"filesrc location=\"$name \" ! $decoder ! alsasink" ); sound = new PlayingSound( name, loop, length, (uint32)pipeline ); Gst.Bus bus = pipeline.get_bus(); bus.add_watch( ( bus, message ) => { assert( this != null ); return onGstreamerMessage( bus, message, sound ); } ); pipeline.set_state( Gst.State.PLAYING ); } catch ( GLib.Error e ) { FsoFramework.theLogger.warning( @"Could not create/launch GStreamer pipeline: $(e.message)" ); return; } } ======================================================================== bails out at runtime with: ERROR:plugin.c:464:_lambda1_: assertion failed: (self != NULL) Aborted ======================================================================== The problem seems to be that the data for the closure (_data_->_data2_) gets unref'ed when the function ends; however Gst is calling the callback later on and then the instance is 0x0. The C code for this function is: ======================================================================== static gboolean player_gstreamer_real_play_sound_co (PlayerGstreamerPlaySoundData* data) { switch (data->_state_) { default: g_assert_not_reached (); case 0: { data->_data2_ = g_slice_new0 (Block2Data); data->_data2_->_ref_count_ = 1; data->_data2_->self = g_object_ref (data->self); data->_data2_->sound = (FsoDevicePlayingSound*) gee_abstract_map_get ((GeeAbstractMap*) ((FsoDeviceBaseAudioPlayer*) data->self)->sounds, data->name); if (data->_data2_->sound != NULL) { data->_inner_error_ = (data->_tmp1_ = g_error_new_literal (FREE_SMARTPHONE_DEVICE_AUDIO_ERROR, FREE_SMARTPHONE_DEVICE_AUDIO_ERROR_ALREADY_PLAYING, data->_tmp0_ = g_strdup_printf ("%s is already playing", data->name)), _g_free0 (data->_tmp0_), data->_tmp1_); if (data->_inner_error_ != NULL) { if ((data->_inner_error_->domain == FREE_SMARTPHONE_DEVICE_AUDIO_ERROR) || (data->_inner_error_->domain == FREE_SMARTPHONE_ERROR)) { g_simple_async_result_set_from_error (data->_async_result, data->_inner_error_); g_error_free (data->_inner_error_); block2_data_unref (data->_data2_); { if (data->_state_ == 0) { g_simple_async_result_complete_in_idle (data->_async_result); } else { g_simple_async_result_complete (data->_async_result); } g_object_unref (data->_async_result); return FALSE; } } else { block2_data_unref (data->_data2_); g_critical ("file %s: line %d: uncaught error: %s", __FILE__, __LINE__, data->_inner_error_->message); g_clear_error (&data->_inner_error_); return FALSE; } } } data->parts = (data->_tmp3_ = data->_tmp2_ = g_strsplit (data->name, ".", 0), data->parts_length1 = _vala_array_length (data->_tmp2_), data->parts_size = data->parts_length1, data->_tmp3_); if (data->parts_length1 == 0) { data->_inner_error_ = g_error_new_literal (FREE_SMARTPHONE_ERROR, FREE_SMARTPHONE_ERROR_INVALID_PARAMETER, "Could not guess media format; need an extension"); if (data->_inner_error_ != NULL) { if ((data->_inner_error_->domain == FREE_SMARTPHONE_DEVICE_AUDIO_ERROR) || (data->_inner_error_->domain == FREE_SMARTPHONE_ERROR)) { g_simple_async_result_set_from_error (data->_async_result, data->_inner_error_); g_error_free (data->_inner_error_); data->parts = (_vala_array_free (data->parts, data->parts_length1, (GDestroyNotify) g_free), NULL); block2_data_unref (data->_data2_); { if (data->_state_ == 0) { g_simple_async_result_complete_in_idle (data->_async_result); } else { g_simple_async_result_complete (data->_async_result); } g_object_unref (data->_async_result); return FALSE; } } else { data->parts = (_vala_array_free (data->parts, data->parts_length1, (GDestroyNotify) g_free), NULL); block2_data_unref (data->_data2_); g_critical ("file %s: line %d: uncaught error: %s", __FILE__, __LINE__, data->_inner_error_->message); g_clear_error (&data->_inner_error_); return FALSE; } } } data->extension = g_strdup (data->parts[data->parts_length1 - 1]); data->decoder = (char*) gee_abstract_map_get ((GeeAbstractMap*) data->self->priv->decoders, data->extension); g_assert (data->decoder != NULL); g_assert (data->self != NULL); { data->pipeline = (data->_tmp5_ = gst_parse_launch (data->_tmp4_ = g_strconcat ("filesrc location=\"", string_to_string (data->name), "\" ! ", string_to_string (data->decoder), " ! alsasink", NULL), &data->_inner_error_), _g_free0 (data->_tmp4_), data->_tmp5_); if (data->_inner_error_ != NULL) { goto __catch1_g_error; goto __finally1; } data->_data2_->sound = (data->_tmp6_ = fso_device_playing_sound_new (data->name, data->loop, data->length, (guint32) data->pipeline), _fso_device_playing_sound_unref0 (data->_data2_->sound), data->_tmp6_); data->bus = gst_element_get_bus (data->pipeline); gst_bus_add_watch (data->bus, __lambda1__gst_bus_func, data->_data2_); gst_element_set_state (data->pipeline, GST_STATE_PLAYING); _gst_object_unref0 (data->pipeline); _gst_object_unref0 (data->bus); } goto __finally1; __catch1_g_error: { data->e = data->_inner_error_; data->_inner_error_ = NULL; { fso_framework_logger_warning (fso_framework_theLogger, data->_tmp7_ = g_strconcat ("Could not create/launch GStreamer pipeline: ", string_to_string (data->e->message), NULL)); _g_free0 (data->_tmp7_); _g_error_free0 (data->e); data->parts = (_vala_array_free (data->parts, data->parts_length1, (GDestroyNotify) g_free), NULL); _g_free0 (data->extension); _g_free0 (data->decoder); block2_data_unref (data->_data2_); { if (data->_state_ == 0) { g_simple_async_result_complete_in_idle (data->_async_result); } else { g_simple_async_result_complete (data->_async_result); } g_object_unref (data->_async_result); return FALSE; } _g_error_free0 (data->e); } } __finally1: if (data->_inner_error_ != NULL) { if ((data->_inner_error_->domain == FREE_SMARTPHONE_DEVICE_AUDIO_ERROR) || (data->_inner_error_->domain == FREE_SMARTPHONE_ERROR)) { g_simple_async_result_set_from_error (data->_async_result, data->_inner_error_); g_error_free (data->_inner_error_); data->parts = (_vala_array_free (data->parts, data->parts_length1, (GDestroyNotify) g_free), NULL); _g_free0 (data->extension); _g_free0 (data->decoder); block2_data_unref (data->_data2_); { if (data->_state_ == 0) { g_simple_async_result_complete_in_idle (data->_async_result); } else { g_simple_async_result_complete (data->_async_result); } g_object_unref (data->_async_result); return FALSE; } } else { data->parts = (_vala_array_free (data->parts, data->parts_length1, (GDestroyNotify) g_free), NULL); _g_free0 (data->extension); _g_free0 (data->decoder); block2_data_unref (data->_data2_); g_critical ("file %s: line %d: uncaught error: %s", __FILE__, __LINE__, data->_inner_error_->message); g_clear_error (&data->_inner_error_); return FALSE; } } data->parts = (_vala_array_free (data->parts, data->parts_length1, (GDestroyNotify) g_free), NULL); _g_free0 (data->extension); _g_free0 (data->decoder); *** block2_data_unref (data->_data2_); } { if (data->_state_ == 0) { g_simple_async_result_complete_in_idle (data->_async_result); } else { g_simple_async_result_complete (data->_async_result); } g_object_unref (data->_async_result); return FALSE; } } } ======================================================================== and the problem seems to be triggered by the line I have marked (***). Is this a bug in Vala or am I using the closure wrongly? Thanks, -- :M: _______________________________________________ Vala-list mailing list Vala-list@gnome.org http://mail.gnome.org/mailman/listinfo/vala-list