00001 #include <glib.h>
00002 #include "dbus-glib.h"
00003 #include <stdio.h>
00004 #include <string.h>
00005
00006 #include "test-thread.h"
00007
00008 typedef struct {
00009 guint32 counters[N_TEST_THREADS];
00010 } ThreadTestData;
00011
00012 static ThreadTestData *
00013 thread_test_data_new (void)
00014 {
00015 ThreadTestData *data;
00016
00017 data = g_new0 (ThreadTestData, 1);
00018
00019 return data;
00020 }
00021
00022 static void
00023 thread_test_data_free (ThreadTestData *data)
00024 {
00025 g_free (data);
00026 }
00027
00028 static DBusMessageHandler *disconnect_handler;
00029 static DBusMessageHandler *filter_handler;
00030 static dbus_int32_t handler_slot = -1;
00031
00032 static DBusHandlerResult
00033 handle_test_message (DBusMessageHandler *handler,
00034 DBusConnection *connection,
00035 DBusMessage *message,
00036 void *user_data)
00037 {
00038 ThreadTestData *data = user_data;
00039 DBusMessageIter iter;
00040 gint32 threadnr;
00041 guint32 counter;
00042 char *str, *expected_str;
00043 GString *counter_str;
00044 int i;
00045
00046 dbus_message_iter_init (message, &iter);
00047
00048 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
00049 {
00050 g_print ("First arg not right type\n");
00051 goto out;
00052 }
00053 threadnr = dbus_message_iter_get_int32 (&iter);
00054 if (threadnr < 0 || threadnr >= N_TEST_THREADS)
00055 {
00056 g_print ("Invalid thread nr\n");
00057 goto out;
00058 }
00059
00060 if (! dbus_message_iter_next (&iter))
00061 {
00062 g_print ("Couldn't get second arg\n");
00063 goto out;
00064 }
00065
00066 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
00067 {
00068 g_print ("Second arg not right type\n");
00069 goto out;
00070 }
00071
00072 counter = dbus_message_iter_get_uint32 (&iter);
00073
00074 if (counter != data->counters[threadnr])
00075 {
00076 g_print ("Thread %d, counter %d, expected %d\n", threadnr, counter, data->counters[threadnr]);
00077 goto out;
00078 }
00079 data->counters[threadnr]++;
00080
00081 if (! dbus_message_iter_next (&iter))
00082 {
00083 g_print ("Couldn't get third arg\n");
00084 goto out;
00085 }
00086
00087 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
00088 {
00089 g_print ("Third arg not right type\n");
00090 goto out;
00091 }
00092
00093 str = dbus_message_iter_get_string (&iter);
00094
00095 if (str == NULL)
00096 {
00097 g_print ("No third arg\n");
00098 goto out;
00099 }
00100
00101 expected_str = g_strdup_printf ("Thread %d-%d\n", threadnr, counter);
00102 if (strcmp (expected_str, str) != 0)
00103 {
00104 g_print ("Wrong string '%s', expected '%s'\n", str, expected_str);
00105 goto out;
00106 }
00107 g_free (str);
00108 g_free (expected_str);
00109
00110 if (dbus_message_iter_next (&iter))
00111 {
00112 g_print ("Extra args on end of message\n");
00113 goto out;
00114 }
00115
00116 dbus_connection_flush (connection);
00117
00118 counter_str = g_string_new ("");
00119 for (i = 0; i < N_TEST_THREADS; i++)
00120 {
00121 g_string_append_printf (counter_str, "%d ", data->counters[i]);
00122 }
00123 g_print ("%s\r", counter_str->str);
00124 g_string_free (counter_str, TRUE);
00125
00126 out:
00127 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00128 }
00129
00130 static DBusHandlerResult
00131 handle_filter (DBusMessageHandler *handler,
00132 DBusConnection *connection,
00133 DBusMessage *message,
00134 void *user_data)
00135 {
00136 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00137 }
00138
00139 static DBusHandlerResult
00140 handle_disconnect (DBusMessageHandler *handler,
00141 DBusConnection *connection,
00142 DBusMessage *message,
00143 void *user_data)
00144 {
00145 g_print ("connection disconnected\n");
00146 dbus_connection_unref (connection);
00147
00148 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00149 }
00150
00151
00152 static void
00153 new_connection_callback (DBusServer *server,
00154 DBusConnection *new_connection,
00155 void *user_data)
00156 {
00157 const char *test_messages[] = { "org.freedesktop.ThreadTest" };
00158 const char *disconnect_messages[] = { "org.freedesktop.Local.Disconnect" };
00159 DBusMessageHandler *test_message_handler;
00160 ThreadTestData * data;
00161
00162 g_print ("new_connection_callback\n");
00163
00164 dbus_connection_ref (new_connection);
00165 dbus_connection_setup_with_g_main (new_connection, NULL);
00166
00167 data = thread_test_data_new ();
00168
00169 test_message_handler =
00170 dbus_message_handler_new (handle_test_message,
00171 data, (DBusFreeFunction)thread_test_data_free);
00172
00173 if (!dbus_connection_register_handler (new_connection,
00174 test_message_handler,
00175 test_messages, 1))
00176 goto nomem;
00177
00178 if (!dbus_connection_set_data (new_connection,
00179 handler_slot,
00180 test_message_handler,
00181 (DBusFreeFunction)dbus_message_handler_unref))
00182 goto nomem;
00183
00184 if (!dbus_connection_register_handler (new_connection,
00185 disconnect_handler,
00186 disconnect_messages, 1))
00187 goto nomem;
00188
00189 if (!dbus_connection_add_filter (new_connection,
00190 filter_handler))
00191 goto nomem;
00192
00193 return;
00194
00195 nomem:
00196 g_error ("no memory to setup new connection");
00197 }
00198
00199 int
00200 main (int argc, char *argv[])
00201 {
00202 GMainLoop *loop;
00203 DBusServer *server;
00204 DBusError error;
00205
00206 g_thread_init (NULL);
00207 dbus_gthread_init ();
00208
00209 if (argc < 2)
00210 {
00211 fprintf (stderr, "Give the server address as an argument\n");
00212 return 1;
00213 }
00214
00215 dbus_error_init (&error);
00216 server = dbus_server_listen (argv[1], &error);
00217 if (server == NULL)
00218 {
00219 fprintf (stderr, "Failed to start server on %s: %s\n",
00220 argv[1], error.message);
00221 dbus_error_free (&error);
00222 return 1;
00223 }
00224
00225 if (!dbus_connection_allocate_data_slot (&handler_slot))
00226 g_error ("no memory for data slot");
00227
00228 filter_handler =
00229 dbus_message_handler_new (handle_filter, NULL, NULL);
00230 if (filter_handler == NULL)
00231 g_error ("no memory for handler");
00232
00233 disconnect_handler =
00234 dbus_message_handler_new (handle_disconnect, NULL, NULL);
00235 if (disconnect_handler == NULL)
00236 g_error ("no memory for handler");
00237
00238 dbus_server_set_new_connection_function (server,
00239 new_connection_callback,
00240 NULL, NULL);
00241
00242 dbus_server_setup_with_g_main (server, NULL);
00243
00244 loop = g_main_loop_new (NULL, FALSE);
00245 g_main_run (loop);
00246
00247 return 0;
00248 }