Beispiel #1
0
DonnaTaskHelperRc
donna_task_helper (DonnaTask          *task,
                   task_helper_ui      show_ui,
                   task_helper_ui      destroy_ui,
                   gpointer            data)
{
    DonnaTaskHelper th;
    fd_set fds;
    gint fd_task;

    g_return_val_if_fail (DONNA_IS_TASK (task), DONNA_TASK_HELPER_RC_ERROR);
    g_return_val_if_fail (show_ui != NULL, DONNA_TASK_HELPER_RC_ERROR);
    g_return_val_if_fail (destroy_ui != NULL, DONNA_TASK_HELPER_RC_ERROR);

    /* create our eventfd */
    th.fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK);
    if (th.fd == -1)
        return DONNA_TASK_HELPER_RC_ERROR;

    /* init th */
    g_mutex_init (&th.mutex);
    th.has_destroy = 0;
    th.show_ui = show_ui;
    th.destroy_ui = destroy_ui;
    th.data = data;
    th.rc = DONNA_TASK_HELPER_RC_SUCCESS;

    /* get the task-s fd, in case it gets paused/cancelled */
    fd_task = donna_task_get_fd (task);

    g_idle_add ((GSourceFunc) do_show_ui, &th);

    for (;;)
    {
        gint ret;

        FD_ZERO (&fds);
        FD_SET (th.fd, &fds);
        if (fd_task >= 0)
            FD_SET (fd_task, &fds);

        /* block thread until user "answered" (helper_done() was called,
         * unblocking our fd) or the task gets paused/cancelled */
        ret = select (MAX (th.fd, fd_task) + 1, &fds, NULL, NULL, 0);
        if (ret < 0)
        {
            gint _errno = errno;

            if (errno == EINTR)
                continue;

            g_warning ("TaskHelper: Call to select() failed: %s",
                    g_strerror (_errno));
            continue;
        }

        g_mutex_lock (&th.mutex);

        /* normal ending, i.e. user did "answer" -- meaning the UI was
         * destroyed, nothing more to do but free stuff & return */
        if (FD_ISSET (th.fd, &fds))
        {
            g_mutex_unlock (&th.mutex);
            break;
        }

        /* task was paused/cancelled */
        if (FD_ISSET (fd_task, &fds))
        {
            th.rc = DONNA_TASK_HELPER_RC_CANCELLING;
            /* flag that there is (will be) a pending call to destroy_ui. This
             * is used to handle race condition where the user answers while
             * we're doing this */
            th.has_destroy = 1;
            /* disable this for now */
            fd_task = -1;
            /* install the call to destroy the ui */
            g_idle_add ((GSourceFunc) do_destroy_ui, &th);
            /* and block again on our fd (waiting for UI to be destroyed) */
        }

        g_mutex_unlock (&th.mutex);
    }

    close (th.fd);
    g_mutex_clear (&th.mutex);
    return th.rc;
}
Beispiel #2
0
static void
run_shm_transmitter_test (gint flags)
{
  GError *error = NULL;
  FsTransmitter *trans;
  FsStreamTransmitter *st;
  GstBus *bus = NULL;
  GParameter params[1];
  GList *local_cands = NULL;
  GstStateChangeReturn ret;
  FsCandidate *cand;
  GList *remote_cands = NULL;
  int param_count = 0;

  done = FALSE;
  connected_count = 0;
  g_cond_init (&cond);
  g_mutex_init (&test_mutex);

  buffer_count[0] = 0;
  buffer_count[1] = 0;
  received_known[0] = 0;
  received_known[1] = 0;

  got_candidates[0] = FALSE;
  got_candidates[1] = FALSE;
  got_prepared[0] = FALSE;
  got_prepared[1] = FALSE;

  if (unlink ("/tmp/src1") < 0 && errno != ENOENT)
    fail ("Could not unlink /tmp/src1: %s", strerror (errno));
  if (unlink ("/tmp/src2") < 0 && errno != ENOENT)
    fail ("Could not unlink /tmp/src2: %s", strerror (errno));


  local_cands = g_list_append (local_cands, fs_candidate_new (NULL, 1,
          FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "/tmp/src1", 0));
  local_cands = g_list_append (local_cands, fs_candidate_new (NULL, 2,
          FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "/tmp/src2", 0));

  if (flags & FLAG_LOCAL_CANDIDATES)
  {
    memset (params, 0, sizeof (GParameter));

    params[0].name = "preferred-local-candidates";
    g_value_init (&params[0].value, FS_TYPE_CANDIDATE_LIST);
    g_value_take_boxed (&params[0].value, local_cands);

    param_count = 1;
  }


  associate_on_source = !(flags & FLAG_NO_SOURCE);

  if ((flags & FLAG_NOT_SENDING) && (flags & FLAG_RECVONLY_FILTER))
  {
    buffer_count[0] = 20;
    received_known[0] = 20;
  }

  trans = fs_transmitter_new ("shm", 2, 0, &error);

  if (error)
    ts_fail ("Error creating transmitter: (%s:%d) %s",
      g_quark_to_string (error->domain), error->code, error->message);
  ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL");
  g_clear_error (&error);

  if (flags & FLAG_RECVONLY_FILTER)
    ts_fail_unless (g_signal_connect (trans, "get-recvonly-filter",
            G_CALLBACK (get_recvonly_filter), NULL));


  pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler));

  bus = gst_element_get_bus (pipeline);
  gst_bus_add_watch (bus, bus_error_callback, NULL);

  gst_bus_enable_sync_message_emission (bus);
  g_signal_connect (bus, "sync-message::error",
      G_CALLBACK (sync_error_handler), NULL);

  gst_object_unref (bus);

  st = fs_transmitter_new_stream_transmitter (trans, NULL,
      param_count, params, &error);

  if (param_count)
    g_value_unset (&params[0].value);

  if (error)
    ts_fail ("Error creating stream transmitter: (%s:%d) %s",
        g_quark_to_string (error->domain), error->code, error->message);
  ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL");
  g_clear_error (&error);

  g_object_set (st, "sending", !(flags & FLAG_NOT_SENDING), NULL);

  ts_fail_unless (g_signal_connect (st, "new-local-candidate",
      G_CALLBACK (_new_local_candidate), trans),
    "Could not connect new-local-candidate signal");
  ts_fail_unless (g_signal_connect (st, "local-candidates-prepared",
      G_CALLBACK (_candidate_prepared), NULL),
    "Could not connect local-candidates-prepared signal");
  ts_fail_unless (g_signal_connect (st, "error",
      G_CALLBACK (stream_transmitter_error), NULL),
    "Could not connect error signal");
  ts_fail_unless (g_signal_connect (st, "known-source-packet-received",
      G_CALLBACK (_known_source_packet_received), NULL),
    "Could not connect known-source-packet-received signal");
  ts_fail_unless (g_signal_connect (st, "state-changed",
      G_CALLBACK (_state_changed), NULL),
    "Could not connect state-changed signal");

  if (!fs_stream_transmitter_gather_local_candidates (st, &error))
  {
    if (error)
      ts_fail ("Could not start gathering local candidates (%s:%d) %s",
          g_quark_to_string (error->domain), error->code, error->message);
    else
      ts_fail ("Could not start gathering candidates"
          " (without a specified error)");
  }
  else
  {
    ts_fail_unless (error == NULL);
  }
  g_clear_error (&error);

  ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
  ts_fail_if (ret == GST_STATE_CHANGE_FAILURE,
      "Could not set the pipeline to playing");

  if (!(flags & FLAG_LOCAL_CANDIDATES))
  {
    ret = fs_stream_transmitter_force_remote_candidates (st, local_cands,
        &error);
    fs_candidate_list_destroy (local_cands);
    if (error)
      ts_fail ("Error while adding candidate: (%s:%d) %s",
          g_quark_to_string (error->domain), error->code, error->message);
    ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate");
  }
  else
  {
    ts_fail_unless (error == NULL);
  }
  g_clear_error (&error);

  cand = fs_candidate_new (NULL, 1,
          FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, NULL, 0);
  cand->username = g_strdup ("/tmp/src1");
  remote_cands = g_list_prepend (remote_cands, cand);
  cand = fs_candidate_new (NULL, 2,
          FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, NULL, 0);
  cand->username = g_strdup ("/tmp/src2");
  remote_cands = g_list_prepend (remote_cands, cand);
  ret = fs_stream_transmitter_force_remote_candidates (st, remote_cands, &error);
  fs_candidate_list_destroy (remote_cands);
  if (error)
    ts_fail ("Error while adding candidate: (%s:%d) %s",
      g_quark_to_string (error->domain), error->code, error->message);
  ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate");
  g_clear_error (&error);

  g_mutex_lock (&test_mutex);
  while (connected_count < 2)
    g_cond_wait (&cond, &test_mutex);
  g_mutex_unlock (&test_mutex);

  setup_fakesrc (trans, pipeline, 1);
  setup_fakesrc (trans, pipeline, 2);

  g_mutex_lock (&test_mutex);
  while (!done)
    g_cond_wait (&cond, &test_mutex);
  g_mutex_unlock (&test_mutex);

  fail_unless (got_prepared[0] == TRUE);
  fail_unless (got_prepared[1] == TRUE);
  fail_unless (got_candidates[0] == TRUE);
  fail_unless (got_candidates[1] == TRUE);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  if (st)
  {
    fs_stream_transmitter_stop (st);
    g_object_unref (st);
  }

  g_object_unref (trans);

  gst_object_unref (pipeline);

  g_cond_clear (&cond);
  g_mutex_clear (&test_mutex);
}
Beispiel #3
0
extern void
FreeMutex(Mutex mutex)
{
    g_mutex_clear(&mutex);
}
Beispiel #4
0
static void
sync_data_clear (SyncData *data)
{
  g_mutex_clear (&data->mutex);
  g_cond_clear (&data->cond);
}