Index: gst/tcp/gstmultifdsink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/gst/tcp/gstmultifdsink.c,v
retrieving revision 1.55
diff -u -B -b -p -r1.55 gstmultifdsink.c
--- gst/tcp/gstmultifdsink.c	29 Mar 2006 14:00:08 -0000	1.55
+++ gst/tcp/gstmultifdsink.c	24 Apr 2006 14:14:26 -0000
@@ -150,6 +150,7 @@ enum
   /* signals */
   SIGNAL_CLIENT_ADDED,
   SIGNAL_CLIENT_REMOVED,
+  SIGNAL_CLIENT_FD_REMOVED,
 
   LAST_SIGNAL
 };
@@ -471,12 +472,34 @@ gst_multi_fd_sink_class_init (GstMultiFd
    * The given file descriptor was removed from multifdsink. This signal will
    * be emited from the streaming thread so applications should be prepared
    * for that.
+   *
+   * @gstmultifdsink still holds a handle to @fd so it is possible to call
+   * the get-stats signal from this callback. For the same reason it is
+   * not safe to close and reuse @fd in this callback.
    */
   gst_multi_fd_sink_signals[SIGNAL_CLIENT_REMOVED] =
       g_signal_new ("client-removed", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstMultiFdSinkClass,
           client_removed), NULL, NULL, gst_tcp_marshal_VOID__INT_BOXED,
       G_TYPE_NONE, 2, G_TYPE_INT, GST_TYPE_CLIENT_STATUS);
+  /**
+   * GstMultiFdSink::client-fd-removed:
+   * @gstmultifdsink: the multifdsink element that emitted this signal
+   * @fd:             the file descriptor that was removed from multifdsink
+   *
+   * The given file descriptor was removed from multifdsink. This signal will
+   * be emited from the streaming thread so applications should be prepared
+   * for that.
+   *
+   * In this callback, @gstmultifdsink has removed all the information 
+   * associated with @fd and it is therefore not possible to call get-stats
+   * with @fd. It is however safe to close and reuse @fd in the callback.
+   */
+  gst_multi_fd_sink_signals[SIGNAL_CLIENT_FD_REMOVED] =
+      g_signal_new ("client-fd-removed", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstMultiFdSinkClass,
+          client_fd_removed), NULL, NULL, gst_tcp_marshal_VOID__INT,
+      G_TYPE_NONE, 1, G_TYPE_INT);
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_multi_fd_sink_change_state);
@@ -771,6 +794,8 @@ gst_multi_fd_sink_remove_client_link (Gs
   /* lock again before we remove the client completely */
   CLIENTS_LOCK (sink);
 
+  /* fd cannot be resued in the above signal callback so we can safely 
+   * remove it from the hashtable here */
   if (!g_hash_table_remove (sink->fd_hash, &client->fd.fd)) {
     GST_WARNING_OBJECT (sink,
         "[fd %5d] error removing client %p from hash", client->fd.fd, client);
@@ -786,6 +811,13 @@ gst_multi_fd_sink_remove_client_link (Gs
     fclass->removed (sink, client->fd.fd);
 
   g_free (client);
+  CLIENTS_UNLOCK (sink);
+
+  /* and the fd is really gone now */
+  g_signal_emit (G_OBJECT (sink),
+      gst_multi_fd_sink_signals[SIGNAL_CLIENT_FD_REMOVED], 0, fd);
+
+  CLIENTS_LOCK (sink);
 }
 
 /* handle a read on a client fd,
Index: gst/tcp/gstmultifdsink.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/gst/tcp/gstmultifdsink.h,v
retrieving revision 1.24
diff -u -B -b -p -r1.24 gstmultifdsink.h
--- gst/tcp/gstmultifdsink.h	8 Apr 2006 18:09:17 -0000	1.24
+++ gst/tcp/gstmultifdsink.h	24 Apr 2006 14:14:26 -0000
@@ -221,8 +221,9 @@ struct _GstMultiFdSinkClass {
   void (*removed) (GstMultiFdSink *sink, int fd);
 
   /* signals */
-  void (*client_added) (GstElement *element, gchar *host, gint fd);
-  void (*client_removed) (GstElement *element, gchar *host, gint fd);
+  void (*client_added) (GstElement *element, gint fd);
+  void (*client_removed) (GstElement *element, gint fd, GstClientStatus status);
+  void (*client_fd_removed) (GstElement *element, gint fd);
 };
 
 GType gst_multi_fd_sink_get_type (void);
