Replacing evil looping code

Havoc Pennington hp at redhat.com
Mon Nov 6 08:31:34 PST 2006


Alexander Larsson wrote:
> Gnome-vfs has some code that just does:
> 
> 	if (!dbus_connection_send_with_reply (connection->connection,
> 					      message, &pending_call, timeout)) {
> 		dbus_message_unref (message);
> 		*result = GNOME_VFS_ERROR_INTERNAL;
> 		return NULL;
> 	}
> 
> 	dbus_message_unref (message);
> 	
> 	while (!dbus_pending_call_get_completed (pending_call) &&
> 	       dbus_connection_read_write_dispatch (connection->connection, -1))
> 		;
> 
> 	reply = dbus_pending_call_steal_reply (pending_call);
> 
> This is with a non-mainloop private connection, but the approach might
> work for you too.
> 

The reason I don't think this will work for Totem is that it relies on 
making a method call - but if he makes a method call, he'll just get an 
error since the process hasn't started up yet.

If you make a method call on a bus name the bus knows how to start, it 
will block the method call, start the bus name owner, then send along 
the method call; but since Totem is starting the bus name owner itself, 
the bus has no idea one will appear, and just immediately returns a "no 
such name" error.

btw I think the code above is almost exactly equivalent to 
dbus_connection_send_with_reply_and_block; the only difference is that 
you're dispatching other message handlers (send_with_reply_and_block 
would only read_write not read_write_dispatch). So you could process 
incoming signals and method calls while blocking here. Not sure if 
that's intentional.

You can also dbus_pending_call_block() which is equivalent to the second 
half of your code there (minus dispatch).

IOW send_with_reply_and_block basically does 
dbus_connection_send_with_reply followed by dbus_pending_call_block, and 
dbus_pending_call_block basically does "while (!reply) read_write()"

Havoc



More information about the dbus mailing list