On 8/16/17 6:56 AM, Enrico Weigelt, metux IT consult wrote:
> I'd assume that do_CreateInstance() returns the object w/ refcnt=1.
Yes. It returns it as an already_AddRefed<> struct.
> The assignment to nsCOMPtr should increase refcount. Correct ?
No, because nsCOMPtr knows not to increase the refcount when an
already_AddRefed is assigned to it. If it _did_ increase it, that would
be a leak.
> When the function is left, the nsCOMPtr is destroyed, and refcnt
> goes back to 1 (we now have a reference left in the caller's pointer
> field).
The refcount goes to 0 and the object is destroyed. You want to either
list.forget(_retval) or NS_ADDREF(*_retval = list), with the former much
preferred.
> I'd guess getter_AddRefs() causes refcnt to be increased again
No. getter_AddRefs just nulls out the nsCOMPtr (causing it to release
whatever it's holding right now, if anything) so the direct assignment
into the nsCOMPtr's guts will not leak whatever used to be there. It
also makes it clear that there is a reference handoff here: after the
call, the nsCOMPtr is holding a ref, but that ref was originally
incremented inside the getter function being called.
> So, should I use dont_AddRef() here ?
No.
> Is the situation different when using out parameter instead of rval ?
No.
> BTW: what happens when passing nsCOMPtr as a reference (w/o IDL) ?
Nothing special. The code you suggest would work; it's just a bit hard
to reason about at the callsite.
> I'd assume that the last line will fill the caller's ref field w/ the
> pointer and increase the object's refcnt (so it's 2 now), then when
> callee is left, its myref is destroyed and refcnt is back to 1.
>
> Is that correct ?
Yes.
-Boris