2003-09-30 02:43:21 +00:00
/* -*- mode: C; c-file-style: "gnu" -*- */
/* test-profile.c Program that does basic message-response for timing
*
* Copyright ( C ) 2003 Red Hat Inc .
*
2004-08-10 03:07:01 +00:00
* Licensed under the Academic Free License version 2.1
2003-09-30 02:43:21 +00:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
# include <config.h>
# include <glib.h>
2004-06-20 15:28:15 +00:00
# include <dbus/dbus-glib-lowlevel.h>
2003-09-30 02:43:21 +00:00
# include <stdlib.h>
2004-11-22 19:20:29 +00:00
# define N_CLIENT_THREADS 4
# define N_ITERATIONS 40000
2003-09-30 02:43:21 +00:00
# define PAYLOAD_SIZE 30
# define ECHO_PATH " / org / freedesktop / EchoTest"
# define ECHO_INTERFACE "org.freedesktop.EchoTest"
# define ECHO_METHOD "EchoProfile"
static const char * address ;
static unsigned char * payload ;
2004-11-13 07:07:47 +00:00
typedef struct
{
int iterations ;
GMainLoop * loop ;
} ClientData ;
typedef struct
{
int handled ;
GMainLoop * loop ;
int n_clients ;
} ServerData ;
2003-09-30 02:43:21 +00:00
static void
2004-11-13 07:07:47 +00:00
send_echo_method_call ( DBusConnection * connection )
2003-09-30 02:43:21 +00:00
{
DBusMessage * message ;
message = dbus_message_new_method_call ( NULL , ECHO_PATH ,
ECHO_INTERFACE , ECHO_METHOD ) ;
dbus_message_append_args ( message ,
DBUS_TYPE_STRING , " Hello World! " ,
DBUS_TYPE_INT32 , 123456 ,
2004-11-13 07:07:47 +00:00
#if 0
2003-09-30 02:43:21 +00:00
DBUS_TYPE_ARRAY , DBUS_TYPE_BYTE ,
payload , PAYLOAD_SIZE ,
# endif
DBUS_TYPE_INVALID ) ;
dbus_connection_send ( connection , message , NULL ) ;
dbus_message_unref ( message ) ;
dbus_connection_flush ( connection ) ;
}
2004-11-13 07:07:47 +00:00
static void
send_echo_method_return ( DBusConnection * connection ,
DBusMessage * call_message )
{
DBusMessage * message ;
message = dbus_message_new_method_return ( call_message ) ;
dbus_connection_send ( connection , message , NULL ) ;
dbus_message_unref ( message ) ;
dbus_connection_flush ( connection ) ;
}
2003-09-30 02:43:21 +00:00
static DBusHandlerResult
client_filter ( DBusConnection * connection ,
DBusMessage * message ,
void * user_data )
{
2004-11-13 07:07:47 +00:00
ClientData * cd = user_data ;
2003-09-30 02:43:21 +00:00
if ( dbus_message_is_signal ( message ,
DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL ,
" Disconnected " ) )
{
g_printerr ( " Client thread disconnected \n " ) ;
exit ( 1 ) ;
}
2004-11-13 07:07:47 +00:00
else if ( dbus_message_get_type ( message ) = = DBUS_MESSAGE_TYPE_METHOD_RETURN )
2003-09-30 02:43:21 +00:00
{
2004-11-13 07:07:47 +00:00
cd - > iterations + = 1 ;
if ( cd - > iterations > = N_ITERATIONS )
2003-09-30 02:43:21 +00:00
{
g_print ( " Completed %d iterations \n " , N_ITERATIONS ) ;
2004-11-13 07:07:47 +00:00
g_main_loop_quit ( cd - > loop ) ;
2003-09-30 02:43:21 +00:00
}
2004-11-13 07:07:47 +00:00
send_echo_method_call ( connection ) ;
2003-09-30 02:43:21 +00:00
return DBUS_HANDLER_RESULT_HANDLED ;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED ;
}
static void *
thread_func ( void * data )
{
DBusError error ;
GMainContext * context ;
DBusConnection * connection ;
2004-11-13 07:07:47 +00:00
ClientData cd ;
2003-09-30 02:43:21 +00:00
g_printerr ( " Starting client thread \n " ) ;
dbus_error_init ( & error ) ;
connection = dbus_connection_open ( address , & error ) ;
if ( connection = = NULL )
{
g_printerr ( " could not open connection: %s \n " , error . message ) ;
dbus_error_free ( & error ) ;
exit ( 1 ) ;
}
2004-11-13 07:07:47 +00:00
context = g_main_context_new ( ) ;
cd . iterations = 1 ;
cd . loop = g_main_loop_new ( context , FALSE ) ;
2003-09-30 02:43:21 +00:00
if ( ! dbus_connection_add_filter ( connection ,
2004-11-13 07:07:47 +00:00
client_filter , & cd , NULL ) )
2003-09-30 02:43:21 +00:00
g_error ( " no memory " ) ;
dbus_connection_setup_with_g_main ( connection , context ) ;
g_printerr ( " Client thread sending message to prime pingpong \n " ) ;
2004-11-13 07:07:47 +00:00
send_echo_method_call ( connection ) ;
2003-09-30 02:43:21 +00:00
g_printerr ( " Client thread sent message \n " ) ;
g_printerr ( " Client thread entering main loop \n " ) ;
2004-11-13 07:07:47 +00:00
g_main_loop_run ( cd . loop ) ;
2003-09-30 02:43:21 +00:00
g_printerr ( " Client thread exiting main loop \n " ) ;
2004-11-13 07:07:47 +00:00
dbus_connection_disconnect ( connection ) ;
2003-09-30 02:43:21 +00:00
2004-11-13 07:07:47 +00:00
g_main_loop_unref ( cd . loop ) ;
2003-09-30 02:43:21 +00:00
g_main_context_unref ( context ) ;
2004-11-13 07:07:47 +00:00
2003-09-30 02:43:21 +00:00
return NULL ;
}
static DBusHandlerResult
server_filter ( DBusConnection * connection ,
DBusMessage * message ,
void * user_data )
{
2004-11-13 07:07:47 +00:00
ServerData * sd = user_data ;
2003-09-30 02:43:21 +00:00
if ( dbus_message_is_signal ( message ,
DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL ,
" Disconnected " ) )
{
2004-11-13 07:07:47 +00:00
g_printerr ( " Client disconnected from server \n " ) ;
sd - > n_clients - = 1 ;
if ( sd - > n_clients = = 0 )
g_main_loop_quit ( sd - > loop ) ;
2003-09-30 02:43:21 +00:00
}
else if ( dbus_message_is_method_call ( message ,
ECHO_INTERFACE ,
ECHO_METHOD ) )
{
2004-11-13 07:07:47 +00:00
sd - > handled + = 1 ;
send_echo_method_return ( connection , message ) ;
2003-09-30 02:43:21 +00:00
return DBUS_HANDLER_RESULT_HANDLED ;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED ;
}
static void
new_connection_callback ( DBusServer * server ,
DBusConnection * new_connection ,
void * user_data )
2004-11-13 07:07:47 +00:00
{
ServerData * sd = user_data ;
2003-09-30 02:43:21 +00:00
dbus_connection_ref ( new_connection ) ;
dbus_connection_setup_with_g_main ( new_connection , NULL ) ;
if ( ! dbus_connection_add_filter ( new_connection ,
2004-11-13 07:07:47 +00:00
server_filter , sd , NULL ) )
2003-09-30 02:43:21 +00:00
g_error ( " no memory " ) ;
2004-11-13 07:07:47 +00:00
sd - > n_clients + = 1 ;
2003-09-30 02:43:21 +00:00
/* FIXME we leak the handler */
}
int
main ( int argc , char * argv [ ] )
{
DBusError error ;
DBusServer * server ;
2004-11-13 07:07:47 +00:00
GTimer * timer ;
2003-09-30 02:43:21 +00:00
int i ;
2004-11-13 07:07:47 +00:00
double secs ;
ServerData sd ;
2003-09-30 02:43:21 +00:00
g_thread_init ( NULL ) ;
dbus_g_thread_init ( ) ;
dbus_error_init ( & error ) ;
server = dbus_server_listen ( " unix:tmpdir= " DBUS_TEST_SOCKET_DIR ,
& error ) ;
if ( server = = NULL )
{
g_printerr ( " Could not start server: %s \n " ,
error . message ) ;
return 1 ;
}
2004-11-13 07:07:47 +00:00
# ifndef DBUS_DISABLE_ASSERT
g_printerr ( " You should probably turn off assertions before you profile \n " ) ;
# endif
2003-09-30 02:43:21 +00:00
address = dbus_server_get_address ( server ) ;
payload = g_malloc ( PAYLOAD_SIZE ) ;
dbus_server_set_new_connection_function ( server ,
new_connection_callback ,
2004-11-13 07:07:47 +00:00
& sd , NULL ) ;
sd . handled = 0 ;
sd . n_clients = 0 ;
sd . loop = g_main_loop_new ( NULL , FALSE ) ;
2003-09-30 02:43:21 +00:00
dbus_server_setup_with_g_main ( server , NULL ) ;
for ( i = 0 ; i < N_CLIENT_THREADS ; i + + )
{
g_thread_create ( thread_func , NULL , FALSE , NULL ) ;
}
2004-11-13 07:07:47 +00:00
timer = g_timer_new ( ) ;
2003-09-30 02:43:21 +00:00
g_printerr ( " Server thread entering main loop \n " ) ;
2004-11-13 07:07:47 +00:00
g_main_loop_run ( sd . loop ) ;
2003-09-30 02:43:21 +00:00
g_printerr ( " Server thread exiting main loop \n " ) ;
2004-11-13 07:07:47 +00:00
secs = g_timer_elapsed ( timer , NULL ) ;
g_timer_destroy ( timer ) ;
2004-11-22 19:20:29 +00:00
g_printerr ( " %g seconds, %d round trips, %f seconds per pingpong \n " ,
2004-11-13 07:07:47 +00:00
secs , sd . handled , secs / sd . handled ) ;
# ifndef DBUS_DISABLE_ASSERT
g_printerr ( " You should probably --disable-asserts before you profile as they have noticeable overhead \n " ) ;
# endif
g_printerr ( " The following g_warning is because we try to call g_source_remove_poll() after g_source_destroy() in dbus-gmain.c, I think we need to add a source free func that clears out the watch/timeout funcs \n " ) ;
2003-09-30 02:43:21 +00:00
dbus_server_unref ( server ) ;
2004-11-13 07:07:47 +00:00
g_main_loop_unref ( sd . loop ) ;
2003-09-30 02:43:21 +00:00
return 0 ;
}
2004-11-13 07:07:47 +00:00
2003-09-30 02:43:21 +00:00