[Rhythmbox-devel] monkey-media signal cleanups and error handling



Hello,

The attached patch implements error handling separately from the
previous patch, as requested on IRC.  It also ensures that every async
callback queued in the glib main loop holds an object reference.

Index: monkey-media-player-gst.c
===================================================================
RCS file: /cvs/gnome/monkey-media/src/monkey-media-player-gst.c,v
retrieving revision 1.6
diff -u -d -I$Id: -u -r1.6 monkey-media-player-gst.c
--- monkey-media-player-gst.c	25 Jan 2003 20:12:26 -0000	1.6
+++ monkey-media-player-gst.c	29 Jan 2003 07:22:12 -0000
@@ -26,6 +26,7 @@
 #include <gst/control/control.h>
 #include <gst/control/dparam_smooth.h>
 #include <math.h>
+#include <string.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 
 #include "monkey-media.h"
@@ -52,6 +53,8 @@
 
 	gboolean playing;
 
+	gboolean block_errors;
+
 	GstDParam *volume_dparam;
 	float cur_volume;
 	gboolean mute;
@@ -68,6 +71,7 @@
 {
 	EOS,
 	INFO,
+	ERROR,
 	TICK,
 	LAST_SIGNAL
 } MonkeyMediaPlayerSignalType;
@@ -76,8 +80,9 @@
 {
 	GObject *object;
 	MonkeyMediaStreamInfoField info_field;
+	char *error;
 	GValue *info;
-} MonkeyMediaPlayerInfoSignal;
+} MonkeyMediaPlayerSignal;
 
 static guint monkey_media_player_signals[LAST_SIGNAL] = { 0 };
 
@@ -139,6 +144,16 @@
 			      2,
 			      MONKEY_MEDIA_TYPE_STREAM_INFO_FIELD,
 			      G_TYPE_POINTER);
+	monkey_media_player_signals[ERROR] =
+		g_signal_new ("error",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (MonkeyMediaPlayerClass, error),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_POINTER);
 	monkey_media_player_signals[TICK] =
 		g_signal_new ("tick",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -159,7 +174,7 @@
 
 	g_signal_emit (G_OBJECT (mp), monkey_media_player_signals[TICK], 0,
 		       monkey_media_player_get_time (mp));
-
+	
 	return TRUE;
 }
 
@@ -179,6 +194,9 @@
 	mp = MONKEY_MEDIA_PLAYER (object);
 
 	g_source_remove (mp->priv->tick_timeout_id);
+	mp->priv->block_errors = TRUE;
+
+	monkey_media_player_close (mp);
 
 	gst_object_unref (GST_OBJECT (mp->priv->pipeline));
 	gst_object_unref (GST_OBJECT (mp->priv->typefind_pipeline));
@@ -196,7 +214,7 @@
 eos_signal_idle (MonkeyMediaPlayer *mp)
 {
 	g_signal_emit (G_OBJECT (mp), monkey_media_player_signals[EOS], 0);
-
+	g_object_unref (G_OBJECT (mp));
 	return FALSE;
 }
 
@@ -204,9 +222,39 @@
 eos_cb (GstElement *element,
 	MonkeyMediaPlayer *mp)
 {
+	g_object_ref (G_OBJECT (mp));
 	g_idle_add ((GSourceFunc) eos_signal_idle, mp);
 }
 
+static gboolean
+error_signal_idle (MonkeyMediaPlayerSignal *signal)
+{
+	g_signal_emit (G_OBJECT (signal->object), monkey_media_player_signals[ERROR], 0,
+		       signal->error);
+	g_free (signal->error);
+	g_free (signal);
+	MONKEY_MEDIA_PLAYER (signal->object)->priv->block_errors = FALSE;
+	g_object_unref (G_OBJECT (signal->object));
+	return FALSE;
+}
+
+static void
+error_cb (GstElement *element,
+	  GObject *arg1,
+	  char *errmsg,
+	  MonkeyMediaPlayer *mp)
+{
+	MonkeyMediaPlayerSignal *signal;
+	if (mp->priv->block_errors)
+		return;
+	mp->priv->block_errors = TRUE;
+	signal = g_new0 (MonkeyMediaPlayerSignal, 1);
+	signal->object = G_OBJECT (mp);
+	signal->error = g_strdup (errmsg);
+	g_object_ref (G_OBJECT (mp));
+	g_idle_add ((GSourceFunc) error_signal_idle, signal);
+}
+
 static void
 have_type_cb (GstElement *element,
 	      GstCaps *caps,
@@ -217,12 +265,13 @@
 }
 
 static gboolean
-info_signal_idle (MonkeyMediaPlayerInfoSignal *signal)
+info_signal_idle (MonkeyMediaPlayerSignal *signal)
 {
 	g_signal_emit (signal->object, monkey_media_player_signals[INFO], 0,
 		       signal->info_field, signal->info);
 
 	g_free (signal->info);
+	g_object_unref (G_OBJECT (signal->object));
 	g_free (signal);
 
 	return FALSE;
@@ -263,14 +312,15 @@
 
 	if (ev != NULL)
 	{
-		MonkeyMediaPlayerInfoSignal *signal;
+		MonkeyMediaPlayerSignal *signal;
 
-		signal = g_new0 (MonkeyMediaPlayerInfoSignal, 1);
+		signal = g_new0 (MonkeyMediaPlayerSignal, 1);
 
 		signal->info_field = ev->value;
 		signal->info = value;
 		signal->object = G_OBJECT (player);
 
+		g_object_ref (G_OBJECT (player));
 		g_idle_add ((GSourceFunc) info_signal_idle, signal);
 	}
 
@@ -320,6 +370,11 @@
 	g_signal_connect (G_OBJECT (mp->priv->pipeline),
 			  "deep_notify",
 			  G_CALLBACK (deep_notify_cb),
+			  mp);
+
+	g_signal_connect (G_OBJECT (mp->priv->pipeline),
+			  "error",
+			  G_CALLBACK (error_cb),
 			  mp);
 
 	mp->priv->src = gst_element_factory_make ("gnomevfssrc", "src");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]