On Tue, Jul 7, 2015 at 9:59 AM, Seth Fowler <mfow...@mozilla.com> wrote:

> I brought this up on IRC, but I think this is worth taking to the list:
>
> Replacing TemporaryRef with already_AddRefed has already caused at least
> one leak because already_AddRefed does not call Release() on the pointer it
> holds if nothing takes ownership of that pointer before its destructor
> runs. TemporaryRef did do that, and this seems like a strictly safer
> approach.
>
> My question is: why doesn’t already_AddRefed call Release() in its
> destructor? The fact that it doesn’t seems to me to be a profoundly
> unintuitive footgun.
>

We have a version of already_AddRefed that automatically releases the value
it holds when it's destroyed; it's called nsCOMPtr.

I don’t think we can trust reviewers to catch this, either. The fact that
> Foo() is declared as:
>
> already_AddRefed<Bar> Foo();
>
> won’t necessarily be obvious from a call site, where the reviewer will
> just see:
>
> Foo();
>

Foo should be MOZ_WARN_UNUSED_RESULT (or whatever that annotation is) then,
as should anything that returns an already_AddRefed.

That call will leak, and if we don’t happen to hit that code path in our
> tests, we may not find out about it until after shipping it.
>

Ensuring that code that is untested works is in general a hard thing to
do.  I'd prefer that people wrote tests. (yes, there may be edge cases in
which this isn't possible)

I’d prefer that already_AddRefed just call Release(), but if there are
> performance arguments against that, then we should be checking for this
> pattern with static analysis. I don’t think the situation as it stands
> should be allowed to remain for long.


There is currently a dynamic analysis (in the form of a fatal assertion) in
the already_AddRefed dtor that I added last year.

- Kyle
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to