Crash when using HAL in multiple libraries

William Jon McCann mccann at jhu.edu
Thu Jun 8 10:56:40 PDT 2006


William Jon McCann wrote:
> David Zeuthen wrote:
> 
>> On Wed, 2006-06-07 at 10:39 -0400, William Jon McCann wrote:
>>
>>>> You might want to try to use dbus_bus_get_private() instead of
>>>> dbus_bus_get() in your libraries. Notwithstanding, this should work so
>>>> it may be a bug in libhal or libdbus (more likely it's libhal). But it
>>>> would be interesting to see if using _private() makes a difference.
>>>
>>>
>>> Nice, I didn't know about dbus_bus_get_private.  
>>
>> It was added some time ago, wasn't always there.
>>
>>
>>> Just to clarify... In this case, unlike dbus_bus_get, the caller owns 
>>> the reference to the connection.  Should this ownership transfer to 
>>> libhal when libhal_ctx_set_dbus_connection is used?  In other words 
>>> who should be responsible for unreffing it?
>>
>>
>>
>> The caller is responsible for unreffing it because otherwise it wouldn't
>> work in a process that loads libraries / plugins where the library /
>> plugin uses libhal. Plus DBusConnection objects from dbus_bus_get are
>> shared between all callers of that function.
>>
>> Btw, IIRC the default behavior of libdbus is to call exit(1) on
>> disconnects unless you call dbus_connection_set_exit_connect(connection,
>> FALSE). So you never really want to unref connections obtained through
>> dbus_bus_get().
> 
> 
> OK, in that case then libhal_ctx_set_dbus_connection should probably ref 
> the connection and then unref in libhal_ctx_shutdown, right?  That 
> should handle both private and shared connections correctly.

Oh nevermind.  This won't work either because you can't do a final unref 
of a private connection either.  You need to disconnect first.  Which 
seems a bit strange since you aren't allowed to disconnect a shared 
connection and there doesn't seem to be any API to determine if a 
connection is private.  I suppose there should probably be a 
dbus_connection_get_is_private().

So, the way it works now is if you are using a private connection with 
libhal I guess you'll need to do something like this in an application 
when shutting down libhal:

{
	DBusError error;
#if USE_PRIVATE_DBUS_CONNECTION
	DBusConnection *conn;

	conn = libhal_ctx_get_dbus_connection (ctx);
#endif

	dbus_error_init (&error);
	if (! libhal_ctx_shutdown (ctx, &error)) {
		/* handle error */
		dbus_error_free (&error);
		return;
	}

#if USE_PRIVATE_DBUS_CONNECTION
	dbus_connection_disconnect (conn);
#endif
}

Maybe this leaks the connection though since I think the disconnect 
happens async.  So, probably need to connect to disconnect signal to do 
  the final unref.

Jon


More information about the hal mailing list