Re: [Vala] Problem with Closure in Coroutine

2009-12-13 Thread Jürg Billeter
On Sat, 2009-12-12 at 19:18 +0100, Michael 'Mickey' Lauer wrote:
 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:

Can you check whether it works if you use add_watch_full() instead of
add_watch()?

Jürg

___
Vala-list mailing list
Vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Problem with Closure in Coroutine

2009-12-13 Thread Michael 'Mickey' Lauer
Am Sonntag, den 13.12.2009, 11:01 +0100 schrieb Jürg Billeter:
 On Sat, 2009-12-12 at 19:18 +0100, Michael 'Mickey' Lauer wrote:
  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:
 
 Can you check whether it works if you use add_watch_full() instead of
 add_watch()?

Awesome, that does it! Should we then change add_watch like

-public uint add_watch (Gst.BusFunc func);
+public uint add_watch (owned Gst.BusFunc func);
?

Thanks a lot,

Mickey.


___
Vala-list mailing list
Vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


Re: [Vala] Problem with Closure in Coroutine

2009-12-13 Thread Jürg Billeter
On Sun, 2009-12-13 at 13:00 +0100, Michael 'Mickey' Lauer wrote:
 Am Sonntag, den 13.12.2009, 11:01 +0100 schrieb Jürg Billeter:
  On Sat, 2009-12-12 at 19:18 +0100, Michael 'Mickey' Lauer wrote:
   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:
  
  Can you check whether it works if you use add_watch_full() instead of
  add_watch()?
 
 Awesome, that does it! Should we then change add_watch like
 
 -public uint add_watch (Gst.BusFunc func);
 +public uint add_watch (owned Gst.BusFunc func);
 ?

No, this is not possible as the C function gst_bus_add_watch does not
have a GDestroyNotify parameter which is necessary to support owned
delegates. However, I've now fixed the binding to always use
gst_bus_add_watch_full to avoid such issues.

Jürg

___
Vala-list mailing list
Vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list


[Vala] Problem with Closure in Coroutine

2009-12-12 Thread Michael 'Mickey' Lauer
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_ =