Fixed gst_play_dispose function so that GstPlay objects can be unrefed safely.
authorJulien Moutte <julien@moutte.net>
Tue, 7 Jan 2003 19:02:44 +0000 (19:02 +0000)
committerJulien Moutte <julien@moutte.net>
Tue, 7 Jan 2003 19:02:44 +0000 (19:02 +0000)
Original commit message from CVS:
Fixed gst_play_dispose function so that GstPlay objects can be unrefed safely.
Optimized some g_idle_add for the signal poller.

gst-libs/gst/play/play.old.c
gst-libs/gst/play/play.old.h

index 2e9edea7387fdb26d236584b2f236578c281e72d..ee7d5f6ee56781b37beb2367dd771d5eed44a79a 100644 (file)
@@ -73,8 +73,8 @@ static void         gst_play_init                 (GstPlay *play);
 static void         gst_play_class_init                    (GstPlayClass *klass);
 static void         gst_play_dispose               (GObject *object);
 
-static void         gst_play_default_timeout_add    (guint interval, GSourceFunc function, gpointer data);
-static void         gst_play_default_idle_add       (GSourceFunc function, gpointer data);
+static guint         gst_play_default_timeout_add    (guint interval, GSourceFunc function, gpointer data);
+static guint         gst_play_default_idle_add       (GSourceFunc function, gpointer data);
 
 static void         gst_play_set_property          (GObject *object, guint prop_id, 
                                                     const GValue *value, GParamSpec *pspec);
@@ -298,6 +298,9 @@ gst_play_init (GstPlay *play)
        play->video_bin_mutex = g_mutex_new();
        gst_play_set_idle_timeout_funcs(play, gst_play_default_timeout_add, gst_play_default_idle_add);
 
+       /*fixored by dolphy */
+       
+       play->tick_timeout_id = play->idle_timeout_id = play->idle_signal_id = 0;
 }
 
 GstPlay *
@@ -390,6 +393,18 @@ static void
 gst_play_dispose (GObject *object)
 {
        GstPlay *play = GST_PLAY (object);
+       /* fixored by dolphy : Before disposing removing any callback that could
+       be called : time ticks, signal poller, etc...*/
+       if (play->tick_timeout_id)
+               if (!g_source_remove(play->tick_timeout_id))
+                       g_warning("failed to remove timetick timer %d", play->tick_timeout_id);
+       if (play->idle_timeout_id)
+               if (!g_source_remove(play->idle_timeout_id))
+                       g_warning("failed to remove idle timer %d", play->idle_timeout_id);
+       if (play->idle_signal_id)
+               if (!g_source_remove(play->idle_signal_id))
+                       g_warning("failed to remove signal idle timer %d", play->idle_signal_id);
+               
        G_OBJECT_CLASS (parent_class)->dispose (object);
        g_mutex_free(play->audio_bin_mutex);
        g_mutex_free(play->video_bin_mutex);
@@ -413,7 +428,10 @@ callback_pipeline_deep_notify (GstElement *element, GstElement *orig, GParamSpec
        signal->signal_data.info.element = orig;
        signal->signal_data.info.param = param;
        g_async_queue_push(play->signal_queue, signal);
-       play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
+       /* fixored by dolphy : If an idle callback has been added for signal polling
+       no need to put a new one */
+       if (!play->idle_signal_id)
+               play->idle_signal_id = play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
 }
 
 static void
@@ -431,12 +449,12 @@ callback_pipeline_state_change (GstElement *element, GstElementState old, GstEle
        if (GST_IS_PIPELINE (play->pipeline)){
                switch (state) {
                case GST_STATE_PLAYING:
-                       play->idle_add_func ((GSourceFunc) gst_play_idle_callback, play);
-                       play->timeout_add_func (200, (GSourceFunc) gst_play_tick_callback, play);
+                       play->idle_timeout_id = play->idle_add_func ((GSourceFunc) gst_play_idle_callback, play);
+                       play->tick_timeout_id = play->timeout_add_func (200, (GSourceFunc) gst_play_tick_callback, play);
                        if (play->length_nanos == 0LL){
                                /* try to get the length up to 16 times */
                                play->get_length_attempt = 16;
-                               play->timeout_add_func (200, (GSourceFunc) gst_play_get_length_callback, play);
+                               play->timeout_add_func (200, (GSourceFunc) gst_play_get_length_callback, play); 
                        }
                        break;
                default:
@@ -448,7 +466,10 @@ callback_pipeline_state_change (GstElement *element, GstElementState old, GstEle
        signal->signal_data.state.old_state = old;
        signal->signal_data.state.new_state = state;
        g_async_queue_push(play->signal_queue, signal);
-       play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
+       /* fixored by dolphy : If an idle callback has been added for signal polling
+       no need to put a new one */
+       if (!play->idle_signal_id)
+               play->idle_signal_id = play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
 }
 
 static gboolean
@@ -456,7 +477,11 @@ gst_play_idle_signal (GstPlay *play)
 {
        GstPlaySignal *signal;
        gint queue_length;
-
+       
+       /* fixored by dolphy : Added safety check on play before poping */
+       
+       g_return_val_if_fail(GST_IS_PLAY(play), FALSE);
+       
        signal = g_async_queue_try_pop(play->signal_queue);
        if (signal == NULL){
                return FALSE;
@@ -485,6 +510,13 @@ gst_play_idle_signal (GstPlay *play)
 
        g_free(signal);
        queue_length = g_async_queue_length (play->signal_queue);
+       
+       /* fixored by dolphy : If queue length is zero the idle callback will be
+       destroyed */
+       
+       if (!queue_length)
+               play->idle_signal_id = 0;
+       
        return (queue_length > 0);
 }
 
@@ -509,7 +541,10 @@ callback_video_have_xid (GstElement *element, gint xid, GstPlay *play)
        signal->signal_id = HAVE_XID;
        signal->signal_data.video_xid.xid = xid;
        g_async_queue_push(play->signal_queue, signal);
-       play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
+       /* fixored by dolphy : If an idle callback has been added for signal polling
+       no need to put a new one */
+       if (!play->idle_signal_id)
+               play->idle_signal_id = play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
        /*g_print("have xid %d\n", xid);*/
 }
 
@@ -522,7 +557,10 @@ callback_video_have_size (GstElement *element, gint width, gint height, GstPlay
        signal->signal_data.video_size.width = width;
        signal->signal_data.video_size.height = height;
        g_async_queue_push(play->signal_queue, signal);
-       play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
+       /* fixored by dolphy : If an idle callback has been added for signal polling
+       no need to put a new one */
+       if (!play->idle_signal_id)
+               play->idle_signal_id = play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play);
        /*g_print("have size %d x %d\n", width, height);*/
 }
 
@@ -575,6 +613,11 @@ static gboolean
 gst_play_tick_callback (GstPlay *play)
 {
        gint secs;
+       
+       /* fixored by dolphy : Added safety check on play before accessing */
+       
+       g_return_val_if_fail(GST_IS_PLAY(play), FALSE);
+       
        play->clock = gst_bin_get_clock (GST_BIN (play->pipeline));
        play->time_nanos = gst_clock_get_time(play->clock);
        secs = (gint) (play->time_nanos / GST_SECOND);
@@ -589,6 +632,10 @@ gst_play_tick_callback (GstPlay *play)
 static gboolean
 gst_play_idle_callback (GstPlay *play)
 {
+       /* fixored by dolphy : Added safety check on play before iterating */
+       
+       g_return_val_if_fail(GST_IS_PLAY(play), FALSE);
+       
        return gst_bin_iterate (GST_BIN (play->pipeline));
 }
 
@@ -702,22 +749,28 @@ gst_play_default_idle (GstPlayIdleData *idle_data)
        return FALSE;
 }
 
-static void
+static guint
 gst_play_default_timeout_add (guint interval, GSourceFunc function, gpointer data)
 {
        GstPlayIdleData *idle_data = g_new0(GstPlayIdleData, 1);
        idle_data->func = function;
        idle_data->data = data;
-       g_timeout_add (interval, (GSourceFunc)gst_play_default_idle, idle_data);
+       
+       /* fixored by dolphy : here we return the source tag to caller */
+       
+       return g_timeout_add (interval, (GSourceFunc)gst_play_default_idle, idle_data);
 }
 
-static void
+static guint
 gst_play_default_idle_add (GSourceFunc function, gpointer data)
 {
        GstPlayIdleData *idle_data = g_new0(GstPlayIdleData, 1);
        idle_data->func = function;
        idle_data->data = data;
-       g_idle_add ((GSourceFunc)gst_play_default_idle, idle_data);
+       
+       /* fixored by dolphy : here we return the source tag to caller */
+       
+       return g_idle_add ((GSourceFunc)gst_play_default_idle, idle_data);
 }
 
 void
index 16fbb00783af18252068d1a67bff453122651a33..f9bc1e6215517b174b27d050528ef8d040e3d6b4 100644 (file)
@@ -77,8 +77,8 @@ typedef struct _GstPlay          GstPlay;
 typedef struct _GstPlayClass     GstPlayClass;
 typedef struct _GstPlayIdleData  GstPlayIdleData;
 
-typedef void (*GstPlayTimeoutAdd) (guint interval, GSourceFunc function, gpointer data);
-typedef void (*GstPlayIdleAdd)    (GSourceFunc function, gpointer data);
+typedef guint (*GstPlayTimeoutAdd) (guint interval, GSourceFunc function, gpointer data);
+typedef guint (*GstPlayIdleAdd)    (GSourceFunc function, gpointer data);
 
 struct _GstPlay
 {
@@ -116,6 +116,12 @@ struct _GstPlay
        gint64 seek_time;
        gint64 time_nanos;
        gint64 length_nanos;
+       
+       /*fixored by dolphy */
+       
+       guint tick_timeout_id;
+       guint idle_timeout_id;
+       guint idle_signal_id;
 
        GAsyncQueue *signal_queue;