Re: [gmime-devel] GObject unref hell



On 11/6/2013 8:25 AM, Mario Theodoridis wrote:
On 06/11/13 13:31, Jeffrey Stedfast wrote:
On 11/6/2013 4:21 AM, Mario Theodoridis wrote:
>> ....
2. Is there a way to safely unref a GObject, i.e. unref it if it needs
to be? This is mainly because it is not always clear to me when and
when not due to issues like the current.

No, but as a general set of rules:

1. if you create a new object and set it as a child on another object,
you need to unref it
2. when you get an object from another object, you don't - think if it
as returning a const pointer.

example of rule #1:

child = g_mime_child_new ();
g_mime_parent_add_child (parent, child);
g_object_unref (child);

The reason you unref here is because the parent adds a ref to the child
when you add it.

Essentially you own a ref to child, and, once you've added the child to
the parent, the parent *also* owns a ref to the child. Thus there are 2
references to it, but if you are done with the child, you need to unref
it (or you leak a reference to it).

example of rule #2:

child = g_mime_parent_get_child (parent);
// no need to unref child because the parent does not ref the child when
it returns it

// to extend this example further...
g_mime_parent_add_child (parent2, child);
// still don't unref the child because you never ref'd it

In this example, when you get the child from the parent, only the parent
owns a reference to the child. When you add it to parent2, parent2 adds
another reference, which means that now both parent objects own a ref to
the child, but since you still don't own a reference to the child, you
don't unref it.

Yes , this is how i understood it, too.
But i'm still getting these weired errors.
Lookin at the error log, i have a feeling it happens in
> g_mime_message_set_mime_part (message, (GMimeObject*) multipart);
when the old mime_part gets unrefed.

Here's the complete function with error checking removed for brevity.
It rewrites an existing message to reflect its new structure.

msg->message is of type GMimeMessage * and
msg->headerList of GMimeHeaderList *


int mimeFromRgsMsg(msgObj msg, rgsMsg rgMsg) {
[snip]

        if (attCnt == 0) {
            /* remove unneeded multi part */
g_mime_message_set_mime_part (msg->message, (GMimeObject*) part); msg->headerList = g_mime_object_get_header_list((GMimeObject*)part);
            rfunref (part);
            break;
        }

        /* there are many parts */
        multipart = g_mime_multipart_new_with_subtype ("mixed");
        g_mime_multipart_add (multipart, (GMimeObject *) part);
        rfunref (part);
part = NULL; [snip]

g_mime_message_set_mime_part (msg->message, (GMimeObject*) multipart); msg->headerList = g_mime_object_get_header_list((GMimeObject*)multipart);
        rfunref (multipart);

    } while(FALSE);

I would guess that the problem is because you remove the multipart (by setting some other part) on the message object, which unrefs the multipart, and then you set the unref'd multipart back on the message and then unref it again.

Hope that helps,

Jeff

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]