Dbus method call sent but no reply got

Yang Chengwei chengwei.yang at intel.com
Tue Sep 17 02:02:47 PDT 2013


On Mon, Sep 16, 2013 at 05:59:27AM +0000, Fei Zheng wrote:
> Hi,
> 
>  
> 
> I need your help to resolve a problem about making method call but no reply
> got.
> 
>  
> 
> In Dbus_send.c, method call is the sent to remote and block to wait the reply.
> 
> 1.        dbus_bus_get()
> 
> 2.       dbus_message_new_method_call()
> 
> 3.       dbus_connection_send_with_reply_and_block()
> 
>  
> 
> in dbus_recv.c,  message_handler () is registered to handle the method call,
> then enter the main loop to dispatch the message.
> 
> 1.       dbus_bus_get()
> 
> 2.       dbus_bus_request_name()
> 
> 3.       dbus_connection_register_object_path()
> 
> 4.       dbus_connection_read_write_dispatch()
> 
>  
> 
> In message_handler, if signal_handler() is called to send the reply in the this
> function, In Dbus_send.c the caller could get the reply correctly. But if the
> reply is sent asynchronously in a signal handler,  the reply could not be got
> by the caller.
> 
>  
> 
> static DBusHandlerResult  message_handler (DBusConnection *connection,
> DBusMessage *message, void *user_data) 

The message_handler is a user defined callback from libdbus view, and
will be invoked to handle messages. That means when libdbus comes here,
the socket is writable and you can send reply/error. After that, the
socket status will changed to readable and wait for input infinitely.
And later write is invalid and can not get the socket io lock.

I'm wondering why you're trying to handle message in signal handler?

--
Thanks,
Chengwei

> 
>  { 
> 
>                 dmsg  = message;
> 
>                 dconn = connection;      
> 
>                
> 
> #if 1
> 
>                 //reply cannot be got by sender when reply is sent in a signal
> handler.
> 
>  
> 
>                 printf("Create signal\n");
> 
>                 incb = 0;
> 
>                 signal(SIGALRM, sigHandler);
> 
>                 printf("Start timer \n");
> 
>                 alarm(1);             
> 
>                 printf("Increase the reference\n");
> 
>                 dbus_connection_ref(connection);  
> 
>                 dbus_message_ref(message);                 
> 
>  
> 
> #else
> 
> // it is ok to send the reply here.
> 
>                 signal_handler();
> 
> #endif  
> 
>  
> 
>                 return DBUS_HANDLER_RESULT_HANDLED;
> 
> }
> 
>  
> 
> The two file is attached, could you help check what’s wrong with it? Thanks.
> 
>  
> 
> Best regards
> 
> Fei Zheng
> 
>  
> 
> 
> 
> Member of the CSR plc group of companies. CSR plc registered in England and
> Wales, registered number 4187346, registered office Churchill House, Cambridge
> Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
> More information can be found at www.csr.com. Follow CSR on Twitter at http://
> twitter.com/CSR_PLC and read our blog at www.csr.com/blog

> // #include <glib.h>         
>  #include <dbus/dbus.h>                     
> // #include <dbus/dbus-glib.h>                     
> #include <stdio.h>
> #include <signal.h>
> 
> static DBusHandlerResult message_handler(DBusConnection *connection, DBusMessage *message, void *user_data);  
> static void signal_handler();
> 
> DBusConnection *dconn;
> DBusMessage *dmsg;
> int incb = 0;
> 
> #define object_event_filter message_handler
> 
> #define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) \
>     {   printf("%s: D-Bus error in %s: %s (%s)", __FUNCTION__, \
>         dbus_message_get_member((msg)), (err)->name, (err)->message); \
>          dbus_error_free((err)); }
> #define LOG_AND_FREE_DBUS_ERROR(err) \
>     {   printf("%s: D-Bus error: %s (%s)", __FUNCTION__, \
>         (err)->name, (err)->message); \
>         dbus_error_free((err)); }
> 
> 
> static const DBusObjectPathVTable object_vtable =
> {
>     NULL, object_event_filter, NULL, NULL, NULL, NULL
> };
>        
>  int main()  
>  {  
> 
>     DBusConnection *bus;                         
>     DBusError error;                             
>     int res;   
> 
>     dbus_error_init(&error);                     
>                                                 
> 	dbus_threads_init_default();                                                 
>                                                  
>     char object_path[] = "/com/csr/test/path";
>                                                      
>     bus = dbus_bus_get(DBUS_BUS_SESSION, &error);    
>     if (!bus) {                              
>  		printf("Connect d-Bus failed: %s", error.message);  
>                                           
>        dbus_error_free(&error);               
>        return 1;  
>    }  
>    
>     /* request our name on the bus and check for errors */
>     res = dbus_bus_request_name(bus, "com.csr.test", DBUS_NAME_FLAG_REPLACE_EXISTING , &error);
>     if (dbus_error_is_set(&error)) { 
>        printf("Name Error (%s)", error.message);
>        dbus_error_free(&error); 
>     }
>     printf("dbus_bus_request_name, return %d\n", res);        
>     
>     if (dbus_error_is_set(&error)) { 
> 	   printf("add match Error (%s)", error.message);
> 	   dbus_error_free(&error); 
> 	}
> 
> 	printf("Register objext path:%s\n", object_path);	
> 	
>     if (!dbus_connection_register_object_path(bus, object_path,
>             &object_vtable, NULL))
>     {
>         printf("%s: Can't register object path %s for agent!",
>              __FUNCTION__, object_path);
>         return -1;
>     }
> 
> 	while(dbus_connection_read_write_dispatch(bus, -1));	
>     return 0;  
>  }  
>  
> static void sigHandler()
> {
> 	printf("in sigHandler\n");
> 	
> 	signal_handler();
> }
>  
>  
>  static DBusHandlerResult  message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)  
>  {  
>  	dmsg  = message;
> 	dconn = connection; 	
> 	
> #if 1
> 	printf("Create signal\n");
> 	incb = 0;
> 	signal(SIGALRM, sigHandler);
> 	printf("Start timer \n");
> 	alarm(1);    	
> 	printf("Increase the reference\n");
> 	dbus_connection_ref(connection);   
> 	dbus_message_ref(message); 		
> 
> #else
> 	signal_handler();
> #endif	
> 
> 	return DBUS_HANDLER_RESULT_HANDLED;
> }
> 
> static void signal_handler()
> {    
>     DBusMessage *message = dmsg;
>     DBusConnection *connection = dconn;
>     
>     if (dbus_message_is_method_call(message, "com.csr.test.Adapter", "SetProperty"))
> 	{
> 		printf("getProperty is got\n");
>         // reply
>         DBusMessage *reply = dbus_message_new_method_return(message);
> 
>         if (!reply)
>         {
>             printf("%s: Cannot create message reply\n", __FUNCTION__);
>             return;
>         }
>         
> 		printf("Send reply to remote, return %d\n", dbus_connection_send(connection, reply, NULL));        
> 		
> 		printf("Free the message\n");
>         dbus_message_unref(dmsg);		
> 		printf("Free the reply\n");
>         dbus_message_unref(reply);	
> 	}                                        
>     
>     return ;
>  } 
> 

>  #include <glib.h>                               
>  #include <dbus/dbus.h>  
> //#include <dbus/dbus-glib.h>                        
>  #include <stdio.h> 
>  
> 
>  static int send_method_call(DBusConnection *bus);
>  
>  #define DBUS_NAME "com.csr.test"
> //#define DBUS_NAME_AGENT "com.csr.test.agent"
> #define DBUS_PATH "/com/csr/test/path"
> #define DBUS_PATH_AGENT "/com/csr/test/agent"
> #define DBUS_INTERFACE_APAPTER "com.csr.test.Adapter"
> #define DBUS_INTERFACE_AGENT "com.csr.test.Agent"
> 
>   
>  // LOGE and free a D-Bus error
> // Using #define so that __FUNCTION__ resolves usefully
> #define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) \
>     {   printf("%s: D-Bus error in %s: %s (%s)", __FUNCTION__, \
>         dbus_message_get_member((msg)), (err)->name, (err)->message); \
>          dbus_error_free((err)); }
> #define LOG_AND_FREE_DBUS_ERROR(err) \
>     {   printf("%s: D-Bus error: %s (%s)", __FUNCTION__, \
>         (err)->name, (err)->message); \
>         dbus_error_free((err)); }
>  
>  int main ()  
>  {  
>     DBusConnection *bus;                         
>     DBusError error;                             
>                                                      
>     char object_path[] = DBUS_PATH;    
> 
>     dbus_error_init (&error);                    
>                                                  
> 	printf("Connect to dbus\n");                                                 
>     bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
>     if (!bus) {                              
> 	   g_warning("Conenct D-Bus failed: %s", error.message);
>        dbus_error_free(&error);              
>        return 1;
>     }  
>     
> 	printf("Send method call \n");
> 	
> 	send_method_call(bus);
> 
> 	printf("Start loop\n");	
>    
> 	while(dbus_connection_read_write_dispatch(bus, -1));		
> 	
> 	printf("Return from main\n");
>     return 0;  
>  }  
>  
>  #define STRCMP strcmp
>  
>  static int send_method_call(DBusConnection *bus)  
>  {
>     DBusMessage *msg = NULL;
>     DBusMessage *reply = NULL;
>     DBusError error;
>     DBusMessageIter iter,subiter;
> 
> 	char *name = "DiscoverableTimeout";
> 	int discoverable_timeout = 60;	
> 	int pairable_timeout = 0;
> 	char powered = 0;
> 	
>     dbus_error_init(&error);
>      /* Compose the command */
>     printf("Make a method call\n");
>     msg = dbus_message_new_method_call(DBUS_NAME,
>                                        DBUS_PATH,
>                                        DBUS_INTERFACE_APAPTER, "SetProperty");
> 
> 
> 	printf("Send and wait for reply\n");
> 	reply = dbus_connection_send_with_reply_and_block(bus, msg, -1, &error);
> 	
>     if (dbus_error_is_set(&error)) {
>          LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&error, msg);
>          goto done;
>     }	
>     else
>     {
> 	    printf("Reply is got\n");
>     }
> 	    
> done:
>     if (reply) dbus_message_unref(reply);
>     if (msg) dbus_message_unref(msg);
>     
>     return TRUE;
> }
> 
> 

> _______________________________________________
> dbus mailing list
> dbus at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dbus

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/dbus/attachments/20130917/49a75d74/attachment.pgp>


More information about the dbus mailing list