I have an application in which I'm using UDisks to handle some drives and partitions. In my application I have a situation where I have a pointer to a UDisksDrive
that I need to convert to a UDisksObject
pointer through which I can access other interfaces later. I'm quite unclear as to what objects I should unreference and when. In one function, I currently do:
UDisksDrive* drive = udisks_client_get_drive_for_block(client, block);
if(drive == NULL) {
g_object_unref(block);
return NULL;
}
UDisksObject* driveObject = (UDisksObject*) g_dbus_interface_get_object(G_DBUS_INTERFACE(drive));
g_object_unref(drive);
return driveObject;
But I don't know if this is right. It works, but I know that might not necessarily mean anything. The gdbus documentation for g_dbus_interface_get_object()
reads like I shouldn't be unreferencing the returned driveObject
variable when the receiving function is done with it, but I'm not sure. I feel like I should be unreferencing block
before the functions returns too, but I don't know why I'm not. This is a project I only get time to work on here and there, and I feel like perhaps I'd tried it and it caused a crash or exception.
Most of my other code involving UDisks is pretty straight-forward. I _get_
something, use it, and unreference it. It's this stuff that involves interface swapping that I'm a little fuzzy on.
Time to think, research, and a brief chat on IRC has resulted in the following:
Yes, I definitely need to free (unreference) block
before the function returns. Also, g_dbus_interface_get_object()
is the wrong function for this situation. Because I don't care about drive
and just want to returns driveObject
, I need to use g_dbus_interface_dup_object()
instead, which allows the returned pointer to own it's own reference. That makes it so that the caller can free driveObject
safely when it's done with it. So the updated code snippet looks like this:
UDisksDrive* drive = udisks_client_get_drive_for_block(client, block);
if(drive == NULL) {
g_object_unref(blockObject);
g_object_unref(block);
return NULL;
}
UDisksObject* driveObject = (UDisksObject*) g_dbus_interface_dup_object(G_DBUS_INTERFACE(drive));
g_object_unref(block);
g_object_unref(drive);
g_object_unref(blockObject);
return driveObject;