/* This test outputs TAP syntax: http://testanything.org/ */
int
main (int argc, char *argv[])
{
  dbus_int32_t slot_connection = -1;
  dbus_int32_t slot_message = -1;
  dbus_int32_t slot_pending = -1;
  DBusError error;
  DBusConnection *conn;
  DBusMessage *method;
  DBusPendingCall *pending;
  DBusMessage *reply;

  printf ("# Testing pending call error\n");

  dbus_connection_allocate_data_slot (&slot_connection);
  dbus_message_allocate_data_slot (&slot_message);
  dbus_pending_call_allocate_data_slot (&slot_pending);

  dbus_error_init (&error);
  conn = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
  dbus_connection_set_data (conn, slot_connection, (void*)"connection", free_data);
  ++count;
  dbus_connection_set_exit_on_disconnect (conn, FALSE);

  method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
                                         "/org/freedesktop/TestSuite",
                                         "org.freedesktop.TestSuite",
                                         "Exit");
  dbus_message_set_data (method, slot_message, (void*)"method", free_data);
  ++count;

  dbus_connection_send_with_reply (conn, method, &pending, -1);
  dbus_message_unref (method);
  dbus_pending_call_set_data (pending, slot_pending, (void*)"pending", free_data);
  ++count;

  dbus_connection_close (conn);

  dbus_pending_call_block (pending);
  reply = dbus_pending_call_steal_reply (pending);
  dbus_pending_call_unref (pending);
  if (reply == NULL)
    {
      printf ("Bail out! Reply is NULL ***\n");
      exit (1);
    }
  dbus_message_set_data (reply, slot_message, (void*)"reply", free_data);
  ++count;
  if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_ERROR)
    {
      printf ("Bail out! Reply is not error ***\n");
      exit (1);
    }
  dbus_message_unref (reply);

  dbus_connection_unref (conn);

  dbus_connection_free_data_slot (&slot_connection);
  dbus_message_free_data_slot (&slot_message);
  dbus_pending_call_free_data_slot (&slot_pending);

  if (count != 0)
    {
      printf ("not ok # Not all refs were unrefed ***\n");
      exit (1);
    }
  else
    {
      printf ("ok\n# Testing completed\n1..1\n");
      exit (0);
    }
}
示例#2
0
static void
test_pending_call (Fixture *f,
    gconstpointer data)
{
  Thread public_api = {
    f,
    NULL,
    (RefFunc) dbus_pending_call_ref,
    NULL,
    (VoidFunc) dbus_pending_call_unref,
    NULL,
    NULL,
    NULL };
  Thread internal_api = {
    f,
    NULL,
    (RefFunc) _dbus_pending_call_ref_unlocked,
    NULL,
    (VoidFunc) dbus_pending_call_unref,
    f->connection,
    (VoidFunc) _dbus_connection_lock,
    (VoidFunc) _dbus_connection_unlock };
  /* This one can't be used to ref, only to cycle or unref. */
  Thread unref_and_unlock_api = {
    f,
    NULL,
    (RefFunc) _dbus_pending_call_ref_unlocked,
    NULL,
    (VoidFunc) _dbus_pending_call_unref_and_unlock,
    f->connection,
    (VoidFunc) _dbus_connection_lock,
    NULL };
  unsigned i;
  DBusPendingCall *pending_call;

  _dbus_connection_lock (f->connection);
  pending_call = _dbus_pending_call_new_unlocked (f->connection,
      DBUS_TIMEOUT_INFINITE, NULL);
  g_assert (pending_call != NULL);
  _dbus_connection_unlock (f->connection);

  public_api.thing = pending_call;
  internal_api.thing = pending_call;
  unref_and_unlock_api.thing = pending_call;

  if (!dbus_pending_call_set_data (pending_call, pending_call_slot, f,
        last_unref))
    g_error ("OOM");

  for (i = 0; i < f->n_threads; i++)
    {
      if ((i % 2) == 0)
        f->threads[i] = g_thread_new (NULL, ref_thread, &public_api);
      else
        f->threads[i] = g_thread_new (NULL, ref_thread, &internal_api);

      g_assert (f->threads[i] != NULL);
    }

  wait_for_all_threads (f);

  for (i = 0; i < f->n_threads; i++)
    {
      switch (i % 3)
        {
          case 0:
            f->threads[i] = g_thread_new (NULL, cycle_thread, &public_api);
            break;
          case 1:
            f->threads[i] = g_thread_new (NULL, cycle_thread, &internal_api);
            break;
          default:
            f->threads[i] = g_thread_new (NULL, cycle_thread,
                &unref_and_unlock_api);
        }

      g_assert (f->threads[i] != NULL);
    }

  wait_for_all_threads (f);

  for (i = 0; i < f->n_threads; i++)
    {
      switch (i % 3)
        {
          case 0:
            f->threads[i] = g_thread_new (NULL, unref_thread, &public_api);
            break;
          case 1:
            f->threads[i] = g_thread_new (NULL, unref_thread, &internal_api);
            break;
          default:
            f->threads[i] = g_thread_new (NULL, unref_thread,
                &unref_and_unlock_api);
        }

      g_assert (f->threads[i] != NULL);
    }

  wait_for_all_threads (f);

  /* Destroy the pending call. This should be the last-unref. */
  g_assert (!f->last_unref);
  dbus_pending_call_unref (pending_call);
  g_assert (f->last_unref);
}