2004-06-20 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / test / glib / test-profile.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* test-profile.c Program that does basic message-response for timing
3  *
4  * Copyright (C) 2003  Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.0
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 /* FIXME this test is wacky since both client and server keep
25  * sending each other method calls, but nobody sends
26  * a DBUS_MESSAGE_TYPE_METHOD_RETURN
27  */
28
29 #include <config.h>
30 #include <glib.h>
31 #include <dbus/dbus-glib-lowlevel.h>
32 #include <stdlib.h>
33
34 #define N_CLIENT_THREADS 1
35 #define N_ITERATIONS 1000
36 #define PAYLOAD_SIZE 30
37 #define ECHO_PATH "/org/freedesktop/EchoTest"
38 #define ECHO_INTERFACE "org.freedesktop.EchoTest"
39 #define ECHO_METHOD "EchoProfile"
40
41 static const char *address;
42 static unsigned char *payload;
43
44 static void
45 send_echo_message (DBusConnection *connection)
46 {
47   DBusMessage *message;
48
49   message = dbus_message_new_method_call (NULL, ECHO_PATH,
50                                           ECHO_INTERFACE, ECHO_METHOD);
51   dbus_message_append_args (message,
52                             DBUS_TYPE_STRING, "Hello World!",
53                             DBUS_TYPE_INT32, 123456,
54 #if 1
55                             DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
56                             payload, PAYLOAD_SIZE,
57 #endif
58                             DBUS_TYPE_INVALID);
59   
60   dbus_connection_send (connection, message, NULL);
61   dbus_message_unref (message);
62   dbus_connection_flush (connection);
63 }
64
65 static DBusHandlerResult
66 client_filter (DBusConnection     *connection,
67                DBusMessage        *message,
68                void               *user_data)
69 {
70   int *iterations = user_data;
71   
72   if (dbus_message_is_signal (message,
73                               DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
74                               "Disconnected"))
75     {
76       g_printerr ("Client thread disconnected\n");
77       exit (1);
78     }
79   else if (dbus_message_is_method_call (message,
80                                         ECHO_INTERFACE, ECHO_METHOD))
81     {
82       *iterations += 1;
83       if (*iterations >= N_ITERATIONS)
84         {
85           g_print ("Completed %d iterations\n", N_ITERATIONS);
86           exit (0);
87         }
88       send_echo_message (connection);
89       return DBUS_HANDLER_RESULT_HANDLED;
90     }
91   
92   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
93 }
94
95 static void*
96 thread_func (void *data)
97 {
98   DBusError error;
99   GMainContext *context;
100   GMainLoop *loop;
101   DBusConnection *connection;
102   int iterations;
103   
104   g_printerr ("Starting client thread\n");
105   
106   dbus_error_init (&error);
107   connection = dbus_connection_open (address, &error);
108   if (connection == NULL)
109     {
110       g_printerr ("could not open connection: %s\n", error.message);
111       dbus_error_free (&error);
112       exit (1);
113     }
114
115   iterations = 1;
116   
117   if (!dbus_connection_add_filter (connection,
118                                    client_filter, &iterations, NULL))
119     g_error ("no memory");
120   
121   context = g_main_context_new ();
122   loop = g_main_loop_new (context, FALSE);
123   
124   dbus_connection_setup_with_g_main (connection, context);
125
126   g_printerr ("Client thread sending message to prime pingpong\n");
127   send_echo_message (connection);
128   g_printerr ("Client thread sent message\n");
129
130   g_printerr ("Client thread entering main loop\n");
131   g_main_loop_run (loop);
132   g_printerr ("Client thread exiting main loop\n");
133   
134   g_main_loop_unref (loop);
135   g_main_context_unref (context);
136
137   return NULL;
138 }
139
140 static DBusHandlerResult
141 server_filter (DBusConnection     *connection,
142                DBusMessage        *message,
143                void               *user_data)
144 {
145   if (dbus_message_is_signal (message,
146                               DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
147                               "Disconnected"))
148     {
149       g_printerr ("Server thread disconnected\n");
150       exit (1);
151     }
152   else if (dbus_message_is_method_call (message,
153                                         ECHO_INTERFACE,
154                                         ECHO_METHOD))
155     {
156       send_echo_message (connection);
157       return DBUS_HANDLER_RESULT_HANDLED;
158     }
159   
160   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
161 }
162
163 static void
164 new_connection_callback (DBusServer     *server,
165                          DBusConnection *new_connection,
166                          void           *user_data)
167 {  
168   dbus_connection_ref (new_connection);
169   dbus_connection_setup_with_g_main (new_connection, NULL);  
170   
171   if (!dbus_connection_add_filter (new_connection,
172                                    server_filter, NULL, NULL))
173     g_error ("no memory");
174   
175
176   /* FIXME we leak the handler */  
177 }
178
179 int
180 main (int argc, char *argv[])
181 {
182   GMainLoop *loop;
183   DBusError error;
184   DBusServer *server;
185   int i;
186   
187   g_thread_init (NULL);
188   dbus_g_thread_init ();
189
190   dbus_error_init (&error);
191   server = dbus_server_listen ("unix:tmpdir="DBUS_TEST_SOCKET_DIR,
192                                &error);
193   if (server == NULL)
194     {
195       g_printerr ("Could not start server: %s\n",
196                   error.message);
197       return 1;
198     }
199
200   address = dbus_server_get_address (server);
201   payload = g_malloc (PAYLOAD_SIZE);
202   
203   dbus_server_set_new_connection_function (server,
204                                            new_connection_callback,
205                                            NULL, NULL);
206   
207   loop = g_main_loop_new (NULL, FALSE);
208
209   dbus_server_setup_with_g_main (server, NULL);
210   
211   for (i = 0; i < N_CLIENT_THREADS; i++)
212     {
213       g_thread_create (thread_func, NULL, FALSE, NULL);
214     }
215
216   g_printerr ("Server thread entering main loop\n");
217   g_main_loop_run (loop);
218   g_printerr ("Server thread exiting main loop\n");
219
220   dbus_server_unref (server);
221   
222   g_main_loop_unref (loop);
223   
224   return 0;
225 }
226