/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
 * Copyright (C) 2006 Wim Taymans <wim at fluendo dot com>
 * Copyright (C) <2011> Collabora Ltd.
 *     Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-multisocketsink
 * @title: multisocketsink
 * @see_also: tcpserversink
 *
 * This plugin writes incoming data to a set of file descriptors. The
 * file descriptors can be added to multisocketsink by emitting the #GstMultiSocketSink::add signal.
 * For each descriptor added, the #GstMultiSocketSink::client-added signal will be called.
 *
 * A client can also be added with the #GstMultiSocketSink::add-full signal
 * that allows for more control over what and how much data a client
 * initially receives.
 *
 * Clients can be removed from multisocketsink by emitting the #GstMultiSocketSink::remove signal. For
 * each descriptor removed, the #GstMultiSocketSink::client-removed signal will be called. The
 * #GstMultiSocketSink::client-removed signal can also be fired when multisocketsink decides that a
 * client is not active anymore or, depending on the value of the
 * #GstMultiSocketSink:recover-policy property, if the client is reading too slowly.
 * In all cases, multisocketsink will never close a file descriptor itself.
 * The user of multisocketsink is responsible for closing all file descriptors.
 * This can for example be done in response to the #GstMultiSocketSink::client-fd-removed signal.
 * Note that multisocketsink still has a reference to the file descriptor when the
 * #GstMultiSocketSink::client-removed signal is emitted, so that "get-stats" can be performed on
 * the descriptor; it is therefore not safe to close the file descriptor in
 * the #GstMultiSocketSink::client-removed signal handler, and you should use the
 * #GstMultiSocketSink::client-fd-removed signal to safely close the fd.
 *
 * Multisocketsink internally keeps a queue of the incoming buffers and uses a
 * separate thread to send the buffers to the clients. This ensures that no
 * client write can block the pipeline and that clients can read with different
 * speeds.
 *
 * When adding a client to multisocketsink, the #GstMultiSocketSink:sync-method property will define
 * which buffer in the queued buffers will be sent first to the client. Clients
 * can be sent the most recent buffer (which might not be decodable by the
 * client if it is not a keyframe), the next keyframe received in
 * multisocketsink (which can take some time depending on the keyframe rate), or the
 * last received keyframe (which will cause a simple burst-on-connect).
 * Multisocketsink will always keep at least one keyframe in its internal buffers
 * when the sync-mode is set to latest-keyframe.
 *
 * There are additional values for the #GstMultiSocketSink:sync-method
 * property to allow finer control over burst-on-connect behaviour. By selecting
 * the 'burst' method a minimum burst size can be chosen, 'burst-keyframe'
 * additionally requires that the burst begin with a keyframe, and
 * 'burst-with-keyframe' attempts to burst beginning with a keyframe, but will
 * prefer a minimum burst size even if it requires not starting with a keyframe.
 *
 * Multisocketsink can be instructed to keep at least a minimum amount of data
 * expressed in time or byte units in its internal queues with the
 * #GstMultiSocketSink:time-min and #GstMultiSocketSink:bytes-min properties respectively.
 * These properties are useful if the application adds clients with the
 * #GstMultiSocketSink::add-full signal to make sure that a burst connect can
 * actually be honored.
 *
 * When streaming data, clients are allowed to read at a different rate than
 * the rate at which multisocketsink receives data. If the client is reading too
 * fast, no data will be send to the client until multisocketsink receives more
 * data. If the client, however, reads too slowly, data for that client will be
 * queued up in multisocketsink. Two properties control the amount of data
 * (buffers) that is queued in multisocketsink: #GstMultiSocketSink:buffers-max and
 * #GstMultiSocketSink:buffers-soft-max. A client that falls behind by
 * #GstMultiSocketSink:buffers-max is removed from multisocketsink forcibly.
 *
 * A client with a lag of at least #GstMultiSocketSink:buffers-soft-max enters the recovery
 * procedure which is controlled with the #GstMultiSocketSink:recover-policy property.
 * A recover policy of NONE will do nothing, RESYNC_LATEST will send the most recently
 * received buffer as the next buffer for the client, RESYNC_SOFT_LIMIT
 * positions the client to the soft limit in the buffer queue and
 * RESYNC_KEYFRAME positions the client at the most recent keyframe in the
 * buffer queue.
 *
 * multisocketsink will by default synchronize on the clock before serving the
 * buffers to the clients. This behaviour can be disabled by setting the sync
 * property to FALSE. Multisocketsink will by default not do QoS and will never
 * drop late buffers.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst-i18n-plugin.h>
#include <gst/net/gstnetcontrolmessagemeta.h>

#include <string.h>

#include "gstmultisocketsink.h"

#ifndef G_OS_WIN32
#include <netinet/in.h>
#endif

#define NOT_IMPLEMENTED 0

GST_DEBUG_CATEGORY_STATIC (multisocketsink_debug);
#define GST_CAT_DEFAULT (multisocketsink_debug)

/* MultiSocketSink signals and args */
enum
{
  /* methods */
  SIGNAL_ADD,
  SIGNAL_ADD_BURST,
  SIGNAL_REMOVE,
  SIGNAL_REMOVE_FLUSH,
  SIGNAL_GET_STATS,

  /* signals */
  SIGNAL_CLIENT_ADDED,
  SIGNAL_CLIENT_REMOVED,
  SIGNAL_CLIENT_SOCKET_REMOVED,

  LAST_SIGNAL
};

#define DEFAULT_SEND_DISPATCHED FALSE
#define DEFAULT_SEND_MESSAGES   FALSE

enum
{
  PROP_0,
  PROP_SEND_DISPATCHED,
  PROP_SEND_MESSAGES,
  PROP_LAST
};

static void gst_multi_socket_sink_finalize (GObject * object);

static void gst_multi_socket_sink_add (GstMultiSocketSink * sink,
    GSocket * socket);
static void gst_multi_socket_sink_add_full (GstMultiSocketSink * sink,
    GSocket * socket, GstSyncMethod sync, GstFormat min_format,
    guint64 min_value, GstFormat max_format, guint64 max_value);
static void gst_multi_socket_sink_remove (GstMultiSocketSink * sink,
    GSocket * socket);
static void gst_multi_socket_sink_remove_flush (GstMultiSocketSink * sink,
    GSocket * socket);
static GstStructure *gst_multi_socket_sink_get_stats (GstMultiSocketSink * sink,
    GSocket * socket);

static void gst_multi_socket_sink_emit_client_added (GstMultiHandleSink * mhs,
    GstMultiSinkHandle handle);
static void gst_multi_socket_sink_emit_client_removed (GstMultiHandleSink * mhs,
    GstMultiSinkHandle handle, GstClientStatus status);

static void gst_multi_socket_sink_stop_pre (GstMultiHandleSink * mhsink);
static void gst_multi_socket_sink_stop_post (GstMultiHandleSink * mhsink);
static gboolean gst_multi_socket_sink_start_pre (GstMultiHandleSink * mhsink);
static gpointer gst_multi_socket_sink_thread (GstMultiHandleSink * mhsink);
static GstMultiHandleClient
    * gst_multi_socket_sink_new_client (GstMultiHandleSink * mhsink,
    GstMultiSinkHandle handle, GstSyncMethod sync_method);
static int gst_multi_socket_sink_client_get_fd (GstMultiHandleClient * client);
static void gst_multi_socket_sink_client_free (GstMultiHandleSink * mhsink,
    GstMultiHandleClient * client);
static void gst_multi_socket_sink_handle_debug (GstMultiSinkHandle handle,
    gchar debug[30]);

static gpointer gst_multi_socket_sink_handle_hash_key (GstMultiSinkHandle
    handle);
static void gst_multi_socket_sink_hash_adding (GstMultiHandleSink * mhsink,
    GstMultiHandleClient * mhclient);
static void gst_multi_socket_sink_hash_removing (GstMultiHandleSink * mhsink,
    GstMultiHandleClient * mhclient);
static void gst_multi_socket_sink_stop_sending (GstMultiSocketSink * sink,
    GstSocketClient * client);

static gboolean gst_multi_socket_sink_socket_condition (GstMultiSinkHandle
    handle, GIOCondition condition, GstMultiSocketSink * sink);

static gboolean gst_multi_socket_sink_unlock (GstBaseSink * bsink);
static gboolean gst_multi_socket_sink_unlock_stop (GstBaseSink * bsink);

static gboolean gst_multi_socket_sink_propose_allocation (GstBaseSink * bsink,
    GstQuery * query);

static void gst_multi_socket_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_multi_socket_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

#define gst_multi_socket_sink_parent_class parent_class
G_DEFINE_TYPE (GstMultiSocketSink, gst_multi_socket_sink,
    GST_TYPE_MULTI_HANDLE_SINK);

static guint gst_multi_socket_sink_signals[LAST_SIGNAL] = { 0 };

static void
gst_multi_socket_sink_class_init (GstMultiSocketSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;
  GstMultiHandleSinkClass *gstmultihandlesink_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;
  gstmultihandlesink_class = (GstMultiHandleSinkClass *) klass;

  gobject_class->set_property = gst_multi_socket_sink_set_property;
  gobject_class->get_property = gst_multi_socket_sink_get_property;
  gobject_class->finalize = gst_multi_socket_sink_finalize;

  /**
   * GstMultiSocketSink:send-dispatched:
   *
   * Sends a GstNetworkMessageDispatched event upstream whenever a buffer
   * is sent to a client.
   * The event is a CUSTOM event name GstNetworkMessageDispatched and
   * contains:
   *
   *   "object"  G_TYPE_OBJECT     : the object identifying the client
   *   "buffer"  GST_TYPE_BUFFER   : the buffer sent to the client
   *
   * Since: 1.8.0
   */
  g_object_class_install_property (gobject_class, PROP_SEND_DISPATCHED,
      g_param_spec_boolean ("send-dispatched", "Send Dispatched",
          "If GstNetworkMessageDispatched events should be pushed",
          DEFAULT_SEND_DISPATCHED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstMultiSocketSink:send-messages:
   *
   * Sends a GstNetworkMessage event upstream whenever a buffer
   * is received from a client.
   * The event is a CUSTOM event name GstNetworkMessage and contains:
   *
   *   "object"  G_TYPE_OBJECT     : the object identifying the client
   *   "buffer"  GST_TYPE_BUFFER   : the buffer with data received from the
   *                                 client
   *
   * Since: 1.8.0
   */
  g_object_class_install_property (gobject_class, PROP_SEND_MESSAGES,
      g_param_spec_boolean ("send-messages", "Send Messages",
          "If GstNetworkMessage events should be pushed", DEFAULT_SEND_MESSAGES,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstMultiSocketSink::add:
   * @gstmultisocketsink: the multisocketsink element to emit this signal on
   * @socket:             the socket to add to multisocketsink
   *
   * Hand the given open socket to multisocketsink to write to.
   */
  gst_multi_socket_sink_signals[SIGNAL_ADD] =
      g_signal_new ("add", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstMultiSocketSinkClass, add), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_SOCKET);
  /**
   * GstMultiSocketSink::add-full:
   * @gstmultisocketsink: the multisocketsink element to emit this signal on
   * @socket:         the socket to add to multisocketsink
   * @sync:           the sync method to use
   * @format_min:     the format of @value_min
   * @value_min:      the minimum amount of data to burst expressed in
   *                  @format_min units.
   * @format_max:     the format of @value_max
   * @value_max:      the maximum amount of data to burst expressed in
   *                  @format_max units.
   *
   * Hand the given open socket to multisocketsink to write to and
   * specify the burst parameters for the new connection.
   */
  gst_multi_socket_sink_signals[SIGNAL_ADD_BURST] =
      g_signal_new ("add-full", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstMultiSocketSinkClass, add_full), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 6,
      G_TYPE_SOCKET, GST_TYPE_SYNC_METHOD, GST_TYPE_FORMAT, G_TYPE_UINT64,
      GST_TYPE_FORMAT, G_TYPE_UINT64);
  /**
   * GstMultiSocketSink::remove:
   * @gstmultisocketsink: the multisocketsink element to emit this signal on
   * @socket:             the socket to remove from multisocketsink
   *
   * Remove the given open socket from multisocketsink.
   */
  gst_multi_socket_sink_signals[SIGNAL_REMOVE] =
      g_signal_new ("remove", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstMultiSocketSinkClass, remove), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_SOCKET);
  /**
   * GstMultiSocketSink::remove-flush:
   * @gstmultisocketsink: the multisocketsink element to emit this signal on
   * @socket:             the socket to remove from multisocketsink
   *
   * Remove the given open socket from multisocketsink after flushing all
   * the pending data to the socket.
   */
  gst_multi_socket_sink_signals[SIGNAL_REMOVE_FLUSH] =
      g_signal_new ("remove-flush", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstMultiSocketSinkClass, remove_flush), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_SOCKET);

  /**
   * GstMultiSocketSink::get-stats:
   * @gstmultisocketsink: the multisocketsink element to emit this signal on
   * @socket:             the socket to get stats of from multisocketsink
   *
   * Get statistics about @socket. This function returns a GstStructure.
   *
   * Returns: a GstStructure with the statistics. The structure contains
   *     values that represent: total number of bytes sent, time
   *     when the client was added, time when the client was
   *     disconnected/removed, time the client is/was active, last activity
   *     time (in epoch seconds), number of buffers dropped.
   *     All times are expressed in nanoseconds (GstClockTime).
   */
  gst_multi_socket_sink_signals[SIGNAL_GET_STATS] =
      g_signal_new ("get-stats", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstMultiSocketSinkClass, get_stats), NULL, NULL,
      g_cclosure_marshal_generic, GST_TYPE_STRUCTURE, 1, G_TYPE_SOCKET);

  /**
   * GstMultiSocketSink::client-added:
   * @gstmultisocketsink: the multisocketsink element that emitted this signal
   * @socket:             the socket that was added to multisocketsink
   *
   * The given socket was added to multisocketsink. This signal will
   * be emitted from the streaming thread so application should be prepared
   * for that.
   */
  gst_multi_socket_sink_signals[SIGNAL_CLIENT_ADDED] =
      g_signal_new ("client-added", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      G_TYPE_NONE, 1, G_TYPE_OBJECT);
  /**
   * GstMultiSocketSink::client-removed:
   * @gstmultisocketsink: the multisocketsink element that emitted this signal
   * @socket:             the socket that is to be removed from multisocketsink
   * @status:             the reason why the client was removed
   *
   * The given socket is about to be removed from multisocketsink. This
   * signal will be emitted from the streaming thread so applications should
   * be prepared for that.
   *
   * @gstmultisocketsink still holds a handle to @socket 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 @socket in this callback.
   */
  gst_multi_socket_sink_signals[SIGNAL_CLIENT_REMOVED] =
      g_signal_new ("client-removed", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      G_TYPE_NONE, 2, G_TYPE_SOCKET, GST_TYPE_CLIENT_STATUS);
  /**
   * GstMultiSocketSink::client-socket-removed:
   * @gstmultisocketsink: the multisocketsink element that emitted this signal
   * @socket:             the socket that was removed from multisocketsink
   *
   * The given socket was removed from multisocketsink. This signal will
   * be emitted from the streaming thread so applications should be prepared
   * for that.
   *
   * In this callback, @gstmultisocketsink has removed all the information
   * associated with @socket and it is therefore not possible to call get-stats
   * with @socket. It is however safe to close() and reuse @fd in the callback.
   */
  gst_multi_socket_sink_signals[SIGNAL_CLIENT_SOCKET_REMOVED] =
      g_signal_new ("client-socket-removed", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      G_TYPE_NONE, 1, G_TYPE_SOCKET);

  gst_element_class_set_static_metadata (gstelement_class,
      "Multi socket sink", "Sink/Network",
      "Send data to multiple sockets",
      "Thomas Vander Stichele <thomas at apestaart dot org>, "
      "Wim Taymans <wim@fluendo.com>, "
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_multi_socket_sink_unlock);
  gstbasesink_class->unlock_stop =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_unlock_stop);
  gstbasesink_class->propose_allocation =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_propose_allocation);

  klass->add = GST_DEBUG_FUNCPTR (gst_multi_socket_sink_add);
  klass->add_full = GST_DEBUG_FUNCPTR (gst_multi_socket_sink_add_full);
  klass->remove = GST_DEBUG_FUNCPTR (gst_multi_socket_sink_remove);
  klass->remove_flush = GST_DEBUG_FUNCPTR (gst_multi_socket_sink_remove_flush);
  klass->get_stats = GST_DEBUG_FUNCPTR (gst_multi_socket_sink_get_stats);

  gstmultihandlesink_class->emit_client_added =
      gst_multi_socket_sink_emit_client_added;
  gstmultihandlesink_class->emit_client_removed =
      gst_multi_socket_sink_emit_client_removed;

  gstmultihandlesink_class->stop_pre =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_stop_pre);
  gstmultihandlesink_class->stop_post =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_stop_post);
  gstmultihandlesink_class->start_pre =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_start_pre);
  gstmultihandlesink_class->thread =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_thread);
  gstmultihandlesink_class->new_client =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_new_client);
  gstmultihandlesink_class->client_get_fd =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_client_get_fd);
  gstmultihandlesink_class->client_free =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_client_free);
  gstmultihandlesink_class->handle_debug =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_handle_debug);
  gstmultihandlesink_class->handle_hash_key =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_handle_hash_key);
  gstmultihandlesink_class->hash_adding =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_hash_adding);
  gstmultihandlesink_class->hash_removing =
      GST_DEBUG_FUNCPTR (gst_multi_socket_sink_hash_removing);

  GST_DEBUG_CATEGORY_INIT (multisocketsink_debug, "multisocketsink", 0,
      "Multi socket sink");
}

static void
gst_multi_socket_sink_init (GstMultiSocketSink * this)
{
  GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (this);

  mhsink->handle_hash = g_hash_table_new (g_direct_hash, g_int_equal);

  this->cancellable = g_cancellable_new ();
  this->send_dispatched = DEFAULT_SEND_DISPATCHED;
  this->send_messages = DEFAULT_SEND_MESSAGES;
}

static void
gst_multi_socket_sink_finalize (GObject * object)
{
  GstMultiSocketSink *this = GST_MULTI_SOCKET_SINK (object);

  if (this->cancellable) {
    g_object_unref (this->cancellable);
    this->cancellable = NULL;
  }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

/* methods to emit signals */

static void
gst_multi_socket_sink_emit_client_added (GstMultiHandleSink * mhsink,
    GstMultiSinkHandle handle)
{
  g_signal_emit (mhsink, gst_multi_socket_sink_signals[SIGNAL_CLIENT_ADDED], 0,
      handle.socket);
}

static void
gst_multi_socket_sink_emit_client_removed (GstMultiHandleSink * mhsink,
    GstMultiSinkHandle handle, GstClientStatus status)
{
  g_signal_emit (mhsink, gst_multi_socket_sink_signals[SIGNAL_CLIENT_REMOVED],
      0, handle.socket, status);
}

/* action signals */

static void
gst_multi_socket_sink_add (GstMultiSocketSink * sink, GSocket * socket)
{
  GstMultiSinkHandle handle;

  handle.socket = socket;
  gst_multi_handle_sink_add (GST_MULTI_HANDLE_SINK_CAST (sink), handle);
}

static void
gst_multi_socket_sink_add_full (GstMultiSocketSink * sink, GSocket * socket,
    GstSyncMethod sync, GstFormat min_format, guint64 min_value,
    GstFormat max_format, guint64 max_value)
{
  GstMultiSinkHandle handle;

  handle.socket = socket;
  gst_multi_handle_sink_add_full (GST_MULTI_HANDLE_SINK_CAST (sink), handle,
      sync, min_format, min_value, max_format, max_value);
}

static void
gst_multi_socket_sink_remove (GstMultiSocketSink * sink, GSocket * socket)
{
  GstMultiSinkHandle handle;

  handle.socket = socket;
  gst_multi_handle_sink_remove (GST_MULTI_HANDLE_SINK_CAST (sink), handle);
}

static void
gst_multi_socket_sink_remove_flush (GstMultiSocketSink * sink, GSocket * socket)
{
  GstMultiSinkHandle handle;

  handle.socket = socket;
  gst_multi_handle_sink_remove_flush (GST_MULTI_HANDLE_SINK_CAST (sink),
      handle);
}

static GstStructure *
gst_multi_socket_sink_get_stats (GstMultiSocketSink * sink, GSocket * socket)
{
  GstMultiSinkHandle handle;

  handle.socket = socket;
  return gst_multi_handle_sink_get_stats (GST_MULTI_HANDLE_SINK_CAST (sink),
      handle);
}

static GstMultiHandleClient *
gst_multi_socket_sink_new_client (GstMultiHandleSink * mhsink,
    GstMultiSinkHandle handle, GstSyncMethod sync_method)
{
  GstSocketClient *client;
  GstMultiHandleClient *mhclient;
  GstMultiHandleSinkClass *mhsinkclass =
      GST_MULTI_HANDLE_SINK_GET_CLASS (mhsink);

  /* create client datastructure */
  g_assert (G_IS_SOCKET (handle.socket));
  client = g_new0 (GstSocketClient, 1);
  mhclient = (GstMultiHandleClient *) client;

  mhclient->handle.socket = G_SOCKET (g_object_ref (handle.socket));

  gst_multi_handle_sink_client_init (mhclient, sync_method);
  mhsinkclass->handle_debug (handle, mhclient->debug);

  /* set the socket to non blocking */
  g_socket_set_blocking (handle.socket, FALSE);

  /* we always read from a client */
  mhsinkclass->hash_adding (mhsink, mhclient);

  gst_multi_handle_sink_setup_dscp_client (mhsink, mhclient);

  return mhclient;
}

static int
gst_multi_socket_sink_client_get_fd (GstMultiHandleClient * client)
{
  return g_socket_get_fd (client->handle.socket);
}

static void
gst_multi_socket_sink_client_free (GstMultiHandleSink * mhsink,
    GstMultiHandleClient * client)
{
  g_assert (G_IS_SOCKET (client->handle.socket));

  g_signal_emit (mhsink,
      gst_multi_socket_sink_signals[SIGNAL_CLIENT_SOCKET_REMOVED], 0,
      client->handle.socket);

  g_object_unref (client->handle.socket);
}

static void
gst_multi_socket_sink_handle_debug (GstMultiSinkHandle handle, gchar debug[30])
{
  g_snprintf (debug, 30, "[socket %p]", handle.socket);
}

static gpointer
gst_multi_socket_sink_handle_hash_key (GstMultiSinkHandle handle)
{
  return handle.socket;
}

/* handle a read on a client socket,
 * which either indicates a close or should be ignored
 * returns FALSE if some error occured or the client closed. */
static gboolean
gst_multi_socket_sink_handle_client_read (GstMultiSocketSink * sink,
    GstSocketClient * client)
{
  gboolean ret, do_event;
  gchar dummy[256], *mem, *omem;
  gssize nread;
  GError *err = NULL;
  gboolean first = TRUE;
  GstMultiHandleClient *mhclient = (GstMultiHandleClient *) client;
  gssize navail, maxmem;

  GST_DEBUG_OBJECT (sink, "%s select reports client read", mhclient->debug);

  ret = TRUE;

  navail = g_socket_get_available_bytes (mhclient->handle.socket);
  if (navail < 0)
    return TRUE;

  /* only collect the data in a buffer when we need to send it with an event */
  do_event = sink->send_messages && navail > 0;
  if (do_event) {
    omem = mem = g_malloc (navail);
    maxmem = navail;
  } else {
    mem = dummy;
    maxmem = sizeof (dummy);
  }

  /* just Read 'n' Drop, could also just drop the client as it's not supposed
   * to write to us except for closing the socket, I guess it's because we
   * like to listen to our customers. */
  do {
    GST_DEBUG_OBJECT (sink, "%s client wants us to read", mhclient->debug);

    nread =
        g_socket_receive (mhclient->handle.socket, mem, MIN (navail,
            maxmem), sink->cancellable, &err);

    if (first && nread == 0) {
      /* client sent close, so remove it */
      GST_DEBUG_OBJECT (sink, "%s client asked for close, removing",
          mhclient->debug);
      mhclient->status = GST_CLIENT_STATUS_CLOSED;
      ret = FALSE;
      break;
    } else if (nread < 0) {
      if (err->code == G_IO_ERROR_WOULD_BLOCK)
        break;

      GST_WARNING_OBJECT (sink, "%s could not read: %s",
          mhclient->debug, err->message);
      mhclient->status = GST_CLIENT_STATUS_ERROR;
      ret = FALSE;
      break;
    }
    navail -= nread;
    if (do_event)
      mem += nread;
    first = FALSE;
  } while (navail > 0);
  g_clear_error (&err);

  if (do_event) {
    if (ret) {
      GstBuffer *buf;
      GstEvent *ev;

      buf = gst_buffer_new_wrapped (omem, maxmem);
      ev = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
          gst_structure_new ("GstNetworkMessage",
              "object", G_TYPE_OBJECT, mhclient->handle.socket,
              "buffer", GST_TYPE_BUFFER, buf, NULL));
      gst_buffer_unref (buf);

      gst_pad_push_event (GST_BASE_SINK_PAD (sink), ev);
    } else
      g_free (omem);
  }
  return ret;
}

/**
 * map_memory_output_vector_n:
 * @buf: The #GstBuffer that should be mapped
 * @offset: Offset into the buffer that should be mapped
 * @vectors: (out,array length=num_vectors): an array of #GOutputVector structs to write into
 * @mapinfo: (out,array length=num_vectors): an array of #GstMapInfo structs to write into
 * @num_vectors: the number of elements in @vectors to prevent buffer overruns
 *
 * Maps a buffer into memory, populating a #GOutputVector to use scatter-gather
 * I/O to send the data over a socket.  The whole buffer won't be mapped into
 * memory if it consists of more than @num_vectors #GstMemory s.
 *
 * Use #unmap_n_memorys after you are
 * finished with the mappings.
 *
 * Returns: The number of GstMemorys mapped
 */
static int
map_n_memory_output_vector (GstBuffer * buf, size_t offset,
    GOutputVector * vectors, GstMapInfo * mapinfo, int num_vectors)
{
  guint mem_idx, mem_len;
  gsize mem_skip;
  size_t maxsize;
  int i;

  g_return_val_if_fail (num_vectors > 0, 0);
  memset (vectors, 0, sizeof (GOutputVector) * num_vectors);

  maxsize = gst_buffer_get_size (buf) - offset;
  if (!gst_buffer_find_memory (buf, offset, maxsize, &mem_idx, &mem_len,
          &mem_skip))
    g_error ("Unable to map memory at offset %" G_GSIZE_FORMAT ", buffer "
        "length is %" G_GSIZE_FORMAT, offset, gst_buffer_get_size (buf));

  for (i = 0; i < mem_len && i < num_vectors; i++) {
    GstMapInfo map = { 0 };
    GstMemory *mem = gst_buffer_peek_memory (buf, mem_idx + i);
    if (!gst_memory_map (mem, &map, GST_MAP_READ))
      g_error ("Unable to map memory %p.  This should never happen.", mem);

    if (i == 0) {
      vectors[i].buffer = map.data + mem_skip;
      vectors[i].size = map.size - mem_skip;
    } else {
      vectors[i].buffer = map.data;
      vectors[i].size = map.size;
    }
    mapinfo[i] = map;
  }
  return i;
}

/**
 * map_n_memory_output_vector:
 * @buf: The #GstBuffer that should be mapped
 * @offset: Offset into the buffer that should be mapped
 * @vectors: (out,array length=num_vectors): an array of #GOutputVector structs to write into
 * @num_vectors: the number of elements in @vectors to prevent buffer overruns
 *
 * Returns: The number of GstMemorys mapped
 */
static void
unmap_n_memorys (GstMapInfo * mapinfo, int num_mappings)
{
  int i;
  g_return_if_fail (num_mappings > 0);

  for (i = 0; i < num_mappings; i++)
    gst_memory_unmap (mapinfo[i].memory, &mapinfo[i]);
}

static gsize
gst_buffer_get_cmsg_list (GstBuffer * buf, GSocketControlMessage ** msgs,
    gsize msg_space)
{
  gpointer iter_state = NULL;
  GstMeta *meta;
  gsize msg_count = 0;

  while ((meta = gst_buffer_iterate_meta (buf, &iter_state)) != NULL
      && msg_count < msg_space) {
    if (meta->info->api == GST_NET_CONTROL_MESSAGE_META_API_TYPE)
      msgs[msg_count++] = ((GstNetControlMessageMeta *) meta)->message;
  }

  return msg_count;
}

#define CMSG_MAX 255

static gssize
gst_multi_socket_sink_write (GstMultiSocketSink * sink,
    GSocket * sock, GstBuffer * buffer, gsize bufoffset,
    GCancellable * cancellable, GError ** err)
{
  GstMapInfo maps[8];
  GOutputVector vec[8];
  guint mems_mapped;
  gssize wrote;
  GSocketControlMessage *cmsgs[CMSG_MAX];
  gsize msg_count;

  mems_mapped = map_n_memory_output_vector (buffer, bufoffset, vec, maps, 8);

  msg_count = gst_buffer_get_cmsg_list (buffer, cmsgs, CMSG_MAX);

  wrote =
      g_socket_send_message (sock, NULL, vec, mems_mapped, cmsgs, msg_count, 0,
      cancellable, err);
  unmap_n_memorys (maps, mems_mapped);
  return wrote;
}

/* Handle a write on a client,
 * which indicates a read request from a client.
 *
 * For each client we maintain a queue of GstBuffers that contain the raw bytes
 * we need to send to the client.
 *
 * We first check to see if we need to send streamheaders. If so, we queue them.
 *
 * Then we run into the main loop that tries to send as many buffers as
 * possible. It will first exhaust the mhclient->sending queue and if the queue
 * is empty, it will pick a buffer from the global queue.
 *
 * Sending the buffers from the mhclient->sending queue is basically writing
 * the bytes to the socket and maintaining a count of the bytes that were
 * sent. When the buffer is completely sent, it is removed from the
 * mhclient->sending queue and we try to pick a new buffer for sending.
 *
 * When the sending returns a partial buffer we stop sending more data as
 * the next send operation could block.
 *
 * This functions returns FALSE if some error occured.
 */
static gboolean
gst_multi_socket_sink_handle_client_write (GstMultiSocketSink * sink,
    GstSocketClient * client)
{
  gboolean more;
  gboolean flushing;
  GstClockTime now;
  GTimeVal nowtv;
  GError *err = NULL;
  GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (sink);
  GstMultiHandleClient *mhclient = (GstMultiHandleClient *) client;
  GstMultiHandleSinkClass *mhsinkclass =
      GST_MULTI_HANDLE_SINK_GET_CLASS (mhsink);


  g_get_current_time (&nowtv);
  now = GST_TIMEVAL_TO_TIME (nowtv);

  flushing = mhclient->status == GST_CLIENT_STATUS_FLUSHING;

  more = TRUE;
  do {
    if (!mhclient->sending) {
      /* client is not working on a buffer */
      if (mhclient->bufpos == -1) {
        /* client is too fast, remove from write queue until new buffer is
         * available */
        gst_multi_socket_sink_stop_sending (sink, client);

        /* if we flushed out all of the client buffers, we can stop */
        if (mhclient->flushcount == 0)
          goto flushed;

        return TRUE;
      } else {
        /* client can pick a buffer from the global queue */
        GstBuffer *buf;
        GstClockTime timestamp;

        /* for new connections, we need to find a good spot in the
         * bufqueue to start streaming from */
        if (mhclient->new_connection && !flushing) {
          gint position =
              gst_multi_handle_sink_new_client_position (mhsink, mhclient);

          if (position >= 0) {
            /* we got a valid spot in the queue */
            mhclient->new_connection = FALSE;
            mhclient->bufpos = position;
          } else {
            /* cannot send data to this client yet */
            gst_multi_socket_sink_stop_sending (sink, client);
            return TRUE;
          }
        }

        /* we flushed all remaining buffers, no need to get a new one */
        if (mhclient->flushcount == 0)
          goto flushed;

        /* grab buffer */
        buf = g_array_index (mhsink->bufqueue, GstBuffer *, mhclient->bufpos);
        mhclient->bufpos--;

        /* update stats */
        timestamp = GST_BUFFER_TIMESTAMP (buf);
        if (mhclient->first_buffer_ts == GST_CLOCK_TIME_NONE)
          mhclient->first_buffer_ts = timestamp;
        if (timestamp != -1)
          mhclient->last_buffer_ts = timestamp;

        /* decrease flushcount */
        if (mhclient->flushcount != -1)
          mhclient->flushcount--;

        GST_LOG_OBJECT (sink, "%s client %p at position %d",
            mhclient->debug, client, mhclient->bufpos);

        /* queueing a buffer will ref it */
        mhsinkclass->client_queue_buffer (mhsink, mhclient, buf);

        /* need to start from the first byte for this new buffer */
        mhclient->bufoffset = 0;
      }
    }

    /* see if we need to send something */
    if (mhclient->sending) {
      gssize wrote;
      GstBuffer *head;

      /* pick first buffer from list */
      head = GST_BUFFER (mhclient->sending->data);

      wrote = gst_multi_socket_sink_write (sink, mhclient->handle.socket, head,
          mhclient->bufoffset, sink->cancellable, &err);

      if (wrote < 0) {
        /* hmm error.. */
        if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CLOSED)) {
          goto connection_reset;
        } else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
          /* write would block, try again later */
          GST_LOG_OBJECT (sink, "write would block %p",
              mhclient->handle.socket);
          more = FALSE;
          g_clear_error (&err);
        } else {
          goto write_error;
        }
      } else {
        if (wrote < (gst_buffer_get_size (head) - mhclient->bufoffset)) {
          /* partial write, try again now */
          GST_LOG_OBJECT (sink,
              "partial write on %p of %" G_GSSIZE_FORMAT " bytes",
              mhclient->handle.socket, wrote);
          mhclient->bufoffset += wrote;
        } else {
          if (sink->send_dispatched) {
            gst_pad_push_event (GST_BASE_SINK_PAD (mhsink),
                gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
                    gst_structure_new ("GstNetworkMessageDispatched",
                        "object", G_TYPE_OBJECT, mhclient->handle.socket,
                        "buffer", GST_TYPE_BUFFER, head, NULL)));
          }
          /* complete buffer was written, we can proceed to the next one */
          mhclient->sending = g_slist_remove (mhclient->sending, head);
          gst_buffer_unref (head);
          /* make sure we start from byte 0 for the next buffer */
          mhclient->bufoffset = 0;
        }
        /* update stats */
        mhclient->bytes_sent += wrote;
        mhclient->last_activity_time = now;
        mhsink->bytes_served += wrote;
      }
    }
  } while (more);

  return TRUE;

  /* ERRORS */
flushed:
  {
    GST_DEBUG_OBJECT (sink, "%s flushed, removing", mhclient->debug);
    mhclient->status = GST_CLIENT_STATUS_REMOVED;
    return FALSE;
  }
connection_reset:
  {
    GST_DEBUG_OBJECT (sink, "%s connection reset by peer, removing",
        mhclient->debug);
    mhclient->status = GST_CLIENT_STATUS_CLOSED;
    g_clear_error (&err);
    return FALSE;
  }
write_error:
  {
    GST_WARNING_OBJECT (sink,
        "%s could not write, removing client: %s", mhclient->debug,
        err->message);
    g_clear_error (&err);
    mhclient->status = GST_CLIENT_STATUS_ERROR;
    return FALSE;
  }
}

static void
ensure_condition (GstMultiSocketSink * sink, GstSocketClient * client,
    GIOCondition condition)
{
  GstMultiHandleClient *mhclient = (GstMultiHandleClient *) client;

  if (client->condition == condition)
    return;

  if (client->source) {
    g_source_destroy (client->source);
    g_source_unref (client->source);
  }
  if (condition && sink->main_context) {
    client->source = g_socket_create_source (mhclient->handle.socket,
        condition, sink->cancellable);
    g_source_set_callback (client->source,
        (GSourceFunc) gst_multi_socket_sink_socket_condition,
        gst_object_ref (sink), (GDestroyNotify) gst_object_unref);
    g_source_attach (client->source, sink->main_context);
  } else {
    client->source = NULL;
    condition = 0;
  }
  client->condition = condition;
}

static void
gst_multi_socket_sink_hash_adding (GstMultiHandleSink * mhsink,
    GstMultiHandleClient * mhclient)
{
  GstMultiSocketSink *sink = GST_MULTI_SOCKET_SINK (mhsink);
  GstSocketClient *client = (GstSocketClient *) (mhclient);

  ensure_condition (sink, client,
      G_IO_IN | G_IO_OUT | G_IO_PRI | G_IO_ERR | G_IO_HUP);
}

static void
gst_multi_socket_sink_hash_removing (GstMultiHandleSink * mhsink,
    GstMultiHandleClient * mhclient)
{
  GstMultiSocketSink *sink = GST_MULTI_SOCKET_SINK (mhsink);
  GstSocketClient *client = (GstSocketClient *) (mhclient);

  ensure_condition (sink, client, 0);
}

static void
gst_multi_socket_sink_stop_sending (GstMultiSocketSink * sink,
    GstSocketClient * client)
{
  ensure_condition (sink, client, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP);
}

/* Handle the clients. This is called when a socket becomes ready
 * to read or writable. Badly behaving clients are put on a
 * garbage list and removed.
 */
static gboolean
gst_multi_socket_sink_socket_condition (GstMultiSinkHandle handle,
    GIOCondition condition, GstMultiSocketSink * sink)
{
  GList *clink;
  GstSocketClient *client;
  gboolean ret = TRUE;
  GstMultiHandleClient *mhclient;
  GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (sink);
  GstMultiHandleSinkClass *mhsinkclass =
      GST_MULTI_HANDLE_SINK_GET_CLASS (mhsink);

  CLIENTS_LOCK (mhsink);
  clink = g_hash_table_lookup (mhsink->handle_hash,
      mhsinkclass->handle_hash_key (handle));
  if (clink == NULL) {
    ret = FALSE;
    goto done;
  }

  client = clink->data;
  mhclient = (GstMultiHandleClient *) client;

  if (mhclient->status != GST_CLIENT_STATUS_FLUSHING
      && mhclient->status != GST_CLIENT_STATUS_OK) {
    gst_multi_handle_sink_remove_client_link (mhsink, clink);
    ret = FALSE;
    goto done;
  }

  if ((condition & G_IO_ERR)) {
    GST_WARNING_OBJECT (sink, "%s has error", mhclient->debug);
    mhclient->status = GST_CLIENT_STATUS_ERROR;
    gst_multi_handle_sink_remove_client_link (mhsink, clink);
    ret = FALSE;
    goto done;
  } else if ((condition & G_IO_HUP)) {
    mhclient->status = GST_CLIENT_STATUS_CLOSED;
    gst_multi_handle_sink_remove_client_link (mhsink, clink);
    ret = FALSE;
    goto done;
  }
  if ((condition & G_IO_IN) || (condition & G_IO_PRI)) {
    /* handle client read */
    if (!gst_multi_socket_sink_handle_client_read (sink, client)) {
      gst_multi_handle_sink_remove_client_link (mhsink, clink);
      ret = FALSE;
      goto done;
    }
  }
  if ((condition & G_IO_OUT)) {
    /* handle client write */
    if (!gst_multi_socket_sink_handle_client_write (sink, client)) {
      gst_multi_handle_sink_remove_client_link (mhsink, clink);
      ret = FALSE;
      goto done;
    }
  }

done:
  CLIENTS_UNLOCK (mhsink);

  return ret;
}

static gboolean
gst_multi_socket_sink_timeout (GstMultiSocketSink * sink)
{
  GstClockTime now;
  GTimeVal nowtv;
  GList *clients;
  GstMultiHandleSink *mhsink = GST_MULTI_HANDLE_SINK (sink);

  g_get_current_time (&nowtv);
  now = GST_TIMEVAL_TO_TIME (nowtv);

  CLIENTS_LOCK (mhsink);
  for (clients = mhsink->clients; clients; clients = clients->next) {
    GstSocketClient *client;
    GstMultiHandleClient *mhclient;

    client = clients->data;
    mhclient = (GstMultiHandleClient *) client;
    if (mhsink->timeout > 0
        && now - mhclient->last_activity_time > mhsink->timeout) {
      mhclient->status = GST_CLIENT_STATUS_SLOW;
      gst_multi_handle_sink_remove_client_link (mhsink, clients);
    }
  }
  CLIENTS_UNLOCK (mhsink);

  return FALSE;
}

/* we handle the client communication in another thread so that we do not block
 * the gstreamer thread while we select() on the client fds */
static gpointer
gst_multi_socket_sink_thread (GstMultiHandleSink * mhsink)
{
  GstMultiSocketSink *sink = GST_MULTI_SOCKET_SINK (mhsink);
  GSource *timeout = NULL;

  while (mhsink->running) {
    if (mhsink->timeout > 0) {
      timeout = g_timeout_source_new (mhsink->timeout / GST_MSECOND);

      g_source_set_callback (timeout,
          (GSourceFunc) gst_multi_socket_sink_timeout, gst_object_ref (sink),
          (GDestroyNotify) gst_object_unref);
      g_source_attach (timeout, sink->main_context);
    }

    /* Returns after handling all pending events or when
     * _wakeup() was called. In any case we have to add
     * a new timeout because something happened.
     */
    g_main_context_iteration (sink->main_context, TRUE);

    if (timeout) {
      g_source_destroy (timeout);
      g_source_unref (timeout);
    }
  }

  return NULL;
}

static void
gst_multi_socket_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstMultiSocketSink *sink = GST_MULTI_SOCKET_SINK (object);

  switch (prop_id) {
    case PROP_SEND_DISPATCHED:
      sink->send_dispatched = g_value_get_boolean (value);
      break;
    case PROP_SEND_MESSAGES:
      sink->send_messages = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_multi_socket_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstMultiSocketSink *sink = GST_MULTI_SOCKET_SINK (object);

  switch (prop_id) {
    case PROP_SEND_DISPATCHED:
      g_value_set_boolean (value, sink->send_dispatched);
      break;
    case PROP_SEND_MESSAGES:
      g_value_set_boolean (value, sink->send_messages);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_multi_socket_sink_start_pre (GstMultiHandleSink * mhsink)
{
  GstMultiSocketSink *mssink = GST_MULTI_SOCKET_SINK (mhsink);
  GstMultiHandleSinkClass *mhsinkclass =
      GST_MULTI_HANDLE_SINK_GET_CLASS (mhsink);
  GList *clients;

  GST_INFO_OBJECT (mssink, "starting");

  mssink->main_context = g_main_context_new ();

  CLIENTS_LOCK (mhsink);
  for (clients = mhsink->clients; clients; clients = clients->next) {
    GstSocketClient *client = clients->data;
    GstMultiHandleClient *mhclient = (GstMultiHandleClient *) client;

    if (client->source)
      continue;
    mhsinkclass->hash_adding (mhsink, mhclient);
  }
  CLIENTS_UNLOCK (mhsink);

  return TRUE;
}

static gboolean
multisocketsink_hash_remove (gpointer key, gpointer value, gpointer data)
{
  return TRUE;
}

static void
gst_multi_socket_sink_stop_pre (GstMultiHandleSink * mhsink)
{
  GstMultiSocketSink *mssink = GST_MULTI_SOCKET_SINK (mhsink);

  if (mssink->main_context)
    g_main_context_wakeup (mssink->main_context);
}

static void
gst_multi_socket_sink_stop_post (GstMultiHandleSink * mhsink)
{
  GstMultiSocketSink *mssink = GST_MULTI_SOCKET_SINK (mhsink);

  if (mssink->main_context) {
    g_main_context_unref (mssink->main_context);
    mssink->main_context = NULL;
  }

  g_hash_table_foreach_remove (mhsink->handle_hash, multisocketsink_hash_remove,
      mssink);
}

static gboolean
gst_multi_socket_sink_unlock (GstBaseSink * bsink)
{
  GstMultiSocketSink *sink;

  sink = GST_MULTI_SOCKET_SINK (bsink);

  GST_DEBUG_OBJECT (sink, "set to flushing");
  g_cancellable_cancel (sink->cancellable);
  if (sink->main_context)
    g_main_context_wakeup (sink->main_context);

  return TRUE;
}

/* will be called only between calls to start() and stop() */
static gboolean
gst_multi_socket_sink_unlock_stop (GstBaseSink * bsink)
{
  GstMultiSocketSink *sink;

  sink = GST_MULTI_SOCKET_SINK (bsink);

  GST_DEBUG_OBJECT (sink, "unset flushing");
  g_object_unref (sink->cancellable);
  sink->cancellable = g_cancellable_new ();

  return TRUE;
}

static gboolean
gst_multi_socket_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
  /* we support some meta */
  gst_query_add_allocation_meta (query, GST_NET_CONTROL_MESSAGE_META_API_TYPE,
      NULL);

  return TRUE;
}
