#include <glib.h>
#include <gst/gst.h>

static void
do_nothing(gpointer a,gpointer b)
{
}

gpointer
iterateme (gpointer data)
{
  GstBin *bin = data;

  for (;;) {
    GstIterator *it2 = NULL;

    it2 = gst_bin_iterate_sorted(bin);
    g_assert( gst_iterator_foreach(it2, do_nothing, NULL) == GST_ITERATOR_DONE);
    gst_iterator_free (it2);
  }

  return NULL;
}

gpointer linkme (gpointer data)
{
  GstElement *pipeline = data;
  GstElement *tee;
  GstPad *srcpad, *sinkpad;
  GstElement *bin;
 
  tee = gst_bin_get_by_name(GST_BIN(pipeline), "t");
  g_assert(tee);
  bin = gst_bin_get_by_name(GST_BIN(pipeline), "bin");
  g_assert(bin);


  sinkpad = gst_element_get_static_pad(bin, "sink");
  g_assert(sinkpad);

  srcpad = gst_element_get_request_pad(tee, "src%d");
  g_assert(srcpad);

  for(;;)
    {
      g_assert(GST_PAD_LINK_SUCCESSFUL(gst_pad_link(srcpad, sinkpad)));

      g_assert(gst_pad_unlink(srcpad, sinkpad));
    }

  return NULL;
}

int main (int argc, char **argv)
{
  GstElement *pipeline;
  GstElement *bin;
  GstIterator *it = NULL;
  gboolean done;
  GstElement *item;
  GThread *t1;
  GThread *t2;

  gst_init(&argc, &argv);

  pipeline = gst_parse_launch("fakesrc ! tee name=t ! fakesink",
			      NULL);
  g_assert(pipeline);
  
  bin = gst_parse_bin_from_description("fakesink", TRUE, NULL);
  g_assert(bin);

  gst_element_set_name(bin, "bin");

  gst_bin_add(GST_BIN(pipeline), bin);


  t1 = g_thread_create(linkme, pipeline, TRUE, NULL);
  t2 = g_thread_create(iterateme, pipeline, TRUE, NULL);

  g_assert(t1 && t2);

  g_thread_join(t2);

  g_thread_join(t1);

  return 0;
}
