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