1da4182fb2976608bea64d676677681fdf2cd910bJohn (J/**
2da4182fb2976608bea64d676677681fdf2cd910bJohn (J* Test to make sure we don't get stuck polling a dbus connection
3da4182fb2976608bea64d676677681fdf2cd910bJohn (J* which has no data on the socket.  This was an issue where
4da4182fb2976608bea64d676677681fdf2cd910bJohn (J* one pending call would read all the data off the bus
5da4182fb2976608bea64d676677681fdf2cd910bJohn (J* and the second pending call would not check to see
6da4182fb2976608bea64d676677681fdf2cd910bJohn (J* if its data had already been read before polling the connection
7da4182fb2976608bea64d676677681fdf2cd910bJohn (J* and blocking.
8da4182fb2976608bea64d676677681fdf2cd910bJohn (J**/
9da4182fb2976608bea64d676677681fdf2cd910bJohn (J
10dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h>
11da4182fb2976608bea64d676677681fdf2cd910bJohn (J#include <dbus/dbus.h>
12da4182fb2976608bea64d676677681fdf2cd910bJohn (J#include <dbus/dbus-sysdeps.h>
13da4182fb2976608bea64d676677681fdf2cd910bJohn (J#include <stdio.h>
14da4182fb2976608bea64d676677681fdf2cd910bJohn (J#include <stdlib.h>
15da4182fb2976608bea64d676677681fdf2cd910bJohn (J
16da4182fb2976608bea64d676677681fdf2cd910bJohn (Jstatic void
17da4182fb2976608bea64d676677681fdf2cd910bJohn (J_run_iteration (DBusConnection *conn)
18da4182fb2976608bea64d676677681fdf2cd910bJohn (J{
19da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusPendingCall *echo_pending;
20da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusPendingCall *dbus_pending;
21da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusMessage *method;
22da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusMessage *reply;
23da4182fb2976608bea64d676677681fdf2cd910bJohn (J  char *echo = "echo";
24da4182fb2976608bea64d676677681fdf2cd910bJohn (J
25da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* send the first message */
26da4182fb2976608bea64d676677681fdf2cd910bJohn (J  method = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService",
27da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "/org/freedesktop/TestSuite",
28da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "org.freedesktop.TestSuite",
29da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "Echo");
30da4182fb2976608bea64d676677681fdf2cd910bJohn (J
31da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_message_append_args (method, DBUS_TYPE_STRING, &echo, NULL);
32da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_connection_send_with_reply (conn, method, &echo_pending, -1);
33da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_message_unref (method);
34da4182fb2976608bea64d676677681fdf2cd910bJohn (J
35da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* send the second message */
36da4182fb2976608bea64d676677681fdf2cd910bJohn (J  method = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
37da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         DBUS_PATH_DBUS,
38da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "org.freedesktop.Introspectable",
39da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "Introspect");
40da4182fb2976608bea64d676677681fdf2cd910bJohn (J
41da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_connection_send_with_reply (conn, method, &dbus_pending, -1);
42da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_message_unref (method);
43da4182fb2976608bea64d676677681fdf2cd910bJohn (J
44da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* block on the second message (should return immediately) */
45da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_pending_call_block (dbus_pending);
46da4182fb2976608bea64d676677681fdf2cd910bJohn (J
47da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* block on the first message */
48da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* if it does not return immediately chances
49da4182fb2976608bea64d676677681fdf2cd910bJohn (J     are we hit the block in poll bug */
50da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_pending_call_block (echo_pending);
51da4182fb2976608bea64d676677681fdf2cd910bJohn (J
52da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* check the reply only to make sure we
53da4182fb2976608bea64d676677681fdf2cd910bJohn (J     are not getting errors unrelated
54da4182fb2976608bea64d676677681fdf2cd910bJohn (J     to the block in poll bug */
55da4182fb2976608bea64d676677681fdf2cd910bJohn (J  reply = dbus_pending_call_steal_reply (echo_pending);
56da4182fb2976608bea64d676677681fdf2cd910bJohn (J
57da4182fb2976608bea64d676677681fdf2cd910bJohn (J  if (reply == NULL)
58da4182fb2976608bea64d676677681fdf2cd910bJohn (J    {
59da4182fb2976608bea64d676677681fdf2cd910bJohn (J      printf ("Failed: Reply is NULL ***\n");
60da4182fb2976608bea64d676677681fdf2cd910bJohn (J      exit (1);
61da4182fb2976608bea64d676677681fdf2cd910bJohn (J    }
62da4182fb2976608bea64d676677681fdf2cd910bJohn (J
63da4182fb2976608bea64d676677681fdf2cd910bJohn (J  if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
64da4182fb2976608bea64d676677681fdf2cd910bJohn (J    {
65da4182fb2976608bea64d676677681fdf2cd910bJohn (J      printf ("Failed: Reply is error: %s ***\n", dbus_message_get_error_name (reply));
66da4182fb2976608bea64d676677681fdf2cd910bJohn (J      exit (1);
67da4182fb2976608bea64d676677681fdf2cd910bJohn (J    }
68da4182fb2976608bea64d676677681fdf2cd910bJohn (J
69da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_message_unref (reply);
70da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_pending_call_unref (dbus_pending);
71da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_pending_call_unref (echo_pending);
72da4182fb2976608bea64d676677681fdf2cd910bJohn (J
73da4182fb2976608bea64d676677681fdf2cd910bJohn (J}
74da4182fb2976608bea64d676677681fdf2cd910bJohn (J
75da4182fb2976608bea64d676677681fdf2cd910bJohn (Jint
76da4182fb2976608bea64d676677681fdf2cd910bJohn (Jmain (int argc, char *argv[])
77da4182fb2976608bea64d676677681fdf2cd910bJohn (J{
78da4182fb2976608bea64d676677681fdf2cd910bJohn (J  long start_tv_sec, start_tv_usec;
79da4182fb2976608bea64d676677681fdf2cd910bJohn (J  long end_tv_sec, end_tv_usec;
80da4182fb2976608bea64d676677681fdf2cd910bJohn (J  int i;
81da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusMessage *method;
82da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusConnection *conn;
83da4182fb2976608bea64d676677681fdf2cd910bJohn (J  DBusError error;
84da4182fb2976608bea64d676677681fdf2cd910bJohn (J
85da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* Time each iteration and make sure it doesn't take more than 5 seconds
86da4182fb2976608bea64d676677681fdf2cd910bJohn (J     to complete.  Outside influences may cause connections to take longer
87da4182fb2976608bea64d676677681fdf2cd910bJohn (J     but if it does and we are stuck in a poll call then we know the
88da4182fb2976608bea64d676677681fdf2cd910bJohn (J     stuck in poll bug has come back to haunt us */
89da4182fb2976608bea64d676677681fdf2cd910bJohn (J
90da4182fb2976608bea64d676677681fdf2cd910bJohn (J  printf ("*** Testing stuck in poll\n");
91da4182fb2976608bea64d676677681fdf2cd910bJohn (J
92da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_error_init (&error);
93da4182fb2976608bea64d676677681fdf2cd910bJohn (J
94da4182fb2976608bea64d676677681fdf2cd910bJohn (J  conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
95da4182fb2976608bea64d676677681fdf2cd910bJohn (J
96da4182fb2976608bea64d676677681fdf2cd910bJohn (J  /* run 100 times to make sure */
97da4182fb2976608bea64d676677681fdf2cd910bJohn (J  for (i = 0; i < 100; i++)
98da4182fb2976608bea64d676677681fdf2cd910bJohn (J    {
99da4182fb2976608bea64d676677681fdf2cd910bJohn (J      long delta;
100da4182fb2976608bea64d676677681fdf2cd910bJohn (J
101da4182fb2976608bea64d676677681fdf2cd910bJohn (J      _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
102da4182fb2976608bea64d676677681fdf2cd910bJohn (J      _run_iteration (conn);
103da4182fb2976608bea64d676677681fdf2cd910bJohn (J      _dbus_get_current_time (&end_tv_sec, &end_tv_usec);
104da4182fb2976608bea64d676677681fdf2cd910bJohn (J
105da4182fb2976608bea64d676677681fdf2cd910bJohn (J      /* we just care about seconds */
106da4182fb2976608bea64d676677681fdf2cd910bJohn (J      delta = end_tv_sec - start_tv_sec;
107c1091cbbd2477699dc16f8c8e3d15fea2f68d603John (J      printf ("Iter %i: %lis\n", i, delta);
108da4182fb2976608bea64d676677681fdf2cd910bJohn (J      if (delta >= 5)
109da4182fb2976608bea64d676677681fdf2cd910bJohn (J        {
110da4182fb2976608bea64d676677681fdf2cd910bJohn (J	  printf ("Failed: looks like we might have been be stuck in poll ***\n");
111da4182fb2976608bea64d676677681fdf2cd910bJohn (J	  exit (1);
112da4182fb2976608bea64d676677681fdf2cd910bJohn (J	}
113da4182fb2976608bea64d676677681fdf2cd910bJohn (J    }
114da4182fb2976608bea64d676677681fdf2cd910bJohn (J
115da4182fb2976608bea64d676677681fdf2cd910bJohn (J  method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
116da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "/org/freedesktop/TestSuite",
117da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "org.freedesktop.TestSuite",
118da4182fb2976608bea64d676677681fdf2cd910bJohn (J                                         "Exit");
119da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_connection_send (conn, method, NULL);
120da4182fb2976608bea64d676677681fdf2cd910bJohn (J  dbus_message_unref (method);
121da4182fb2976608bea64d676677681fdf2cd910bJohn (J
122da4182fb2976608bea64d676677681fdf2cd910bJohn (J  printf ("Success ***\n");
123da4182fb2976608bea64d676677681fdf2cd910bJohn (J  exit (0);
124da4182fb2976608bea64d676677681fdf2cd910bJohn (J}
125