2 * Copyright © 2006 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Test to make sure we don't get stuck polling a dbus connection
26 * which has no data on the socket. This was an issue where
27 * one pending call would read all the data off the bus
28 * and the second pending call would not check to see
29 * if its data had already been read before polling the connection
34 #include <dbus/dbus.h>
35 #include <dbus/dbus-sysdeps.h>
40 _run_iteration (DBusConnection *conn)
42 DBusPendingCall *echo_pending;
43 DBusPendingCall *dbus_pending;
46 const char *echo = "echo";
48 /* send the first message */
49 method = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService",
50 "/org/freedesktop/TestSuite",
51 "org.freedesktop.TestSuite",
54 if (!dbus_message_append_args (method, DBUS_TYPE_STRING, &echo, NULL))
56 fprintf (stderr, "Bail out! Failed to append arguments: OOM\n");
60 dbus_connection_send_with_reply (conn, method, &echo_pending, -1);
61 dbus_message_unref (method);
63 /* send the second message */
64 method = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
66 "org.freedesktop.Introspectable",
69 dbus_connection_send_with_reply (conn, method, &dbus_pending, -1);
70 dbus_message_unref (method);
72 /* block on the second message (should return immediately) */
73 dbus_pending_call_block (dbus_pending);
75 /* block on the first message */
76 /* if it does not return immediately chances
77 are we hit the block in poll bug */
78 dbus_pending_call_block (echo_pending);
80 /* check the reply only to make sure we
81 are not getting errors unrelated
82 to the block in poll bug */
83 reply = dbus_pending_call_steal_reply (echo_pending);
87 printf ("Bail out! Reply is NULL ***\n");
91 if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
93 printf ("Bail out! Reply is error: %s ***\n", dbus_message_get_error_name (reply));
97 dbus_message_unref (reply);
98 dbus_pending_call_unref (dbus_pending);
99 dbus_pending_call_unref (echo_pending);
103 /* This test outputs TAP syntax: http://testanything.org/ */
105 main (int argc, char *argv[])
107 long start_tv_sec, start_tv_usec;
108 long end_tv_sec, end_tv_usec;
111 DBusConnection *conn;
114 /* Time each iteration and make sure it doesn't take more than 5 seconds
115 to complete. Outside influences may cause connections to take longer
116 but if it does and we are stuck in a poll call then we know the
117 stuck in poll bug has come back to haunt us */
119 printf ("# Testing stuck in poll\n");
121 dbus_error_init (&error);
123 conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
125 /* run 100 times to make sure */
126 for (i = 0; i < 100; i++)
130 _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
131 _run_iteration (conn);
132 _dbus_get_monotonic_time (&end_tv_sec, &end_tv_usec);
134 /* we just care about seconds */
135 delta = end_tv_sec - start_tv_sec;
136 printf ("ok %d - %lis\n", i + 1, delta);
139 printf ("Bail out! Looks like we might have been be stuck in poll ***\n");
144 method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
145 "/org/freedesktop/TestSuite",
146 "org.freedesktop.TestSuite",
148 dbus_connection_send (conn, method, NULL);
149 dbus_message_unref (method);
151 printf ("# Testing completed\n1..%d\n", i);