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