[Telepathy] tq-qt4 refcount proposal
Andre Moreira Magalhaes
andre.magalhaes at collabora.co.uk
Mon Mar 23 08:04:02 PDT 2009
Simon McVittie wrote:
> Is there a Qt/KDE convention for this sort of thing, or are we in uncharted
> territory here?
> If there's no Qt/KDE convention, we should follow GObject's lead, since it's
> a tried-and-tested refcounted object model that many of us have experience
> with. In particular, we *will* need weak references in a number of places.
Afaik there is no such convention in Qt/KDE world, shared pointers were
introduced in Qt 4.x series and QExplicitlySharedDataPointer in Qt 4.4,
that is not a long time ago.
So I based mostly on WebKit refcounted objects which is quite similar to
> On Fri, 20 Mar 2009 at 17:50:23 -0300, Andre Moreira Magalhaes wrote:
>> 2.1 - Problems:
>> 2.1.1 - Circular dependency:
>> In the ideal world we should use QExplicitlySharedDataPointer<Object> in
>> the library, even for objects that needs to know about each other, for
>> example StreamedMediaChannel that caches the MediaStreams and
>> MediaStreams that have a pointer to the StreamedMediaChannel. We should
>> be careful with this, as we hit circular dependency, which can lead to
>> even more memory leaks when the objects refcount never hits 0.
> Tidying up circular dependencies when a natural end-of-life is reached
> (invalidated signal) seems a reasonable approach; many Telepathy objects
> (Channel, Connection) have such a thing.
> Account and AccountManager might be tricky - there's no natural end-of-life
> for the AccountManager, and Accounts' lives only end if the account is
> deleted by the user (a rare event!). Perhaps Account could weakly ref the
> AccountManager, and the AccountManager could strongly ref the Accounts?
> (In practice, almost every UI will want to have a ref to the AccountManager
> for the entire lifetime of the UI, I think, so the Accounts won't be GC'd
> until later.)
Yep. that's another solution, what I did for now in my experimental
shared branch was to make AccountManager do not cache Accounts, and
Accounts have strong ref to the AccountManager.
>> 3 - Naming:
>> So I propose to have a template class SharedPtr that inherits
>> QExplicitlySharedDataPointer, and a class named SharedData that is a
>> typedef for QSharedData (in case we want to change to use another class
>> in the future, we don't need to change all classes). We may want to make
>> SharedData call deleteLater on ref==0 instead of delete for example.
>> So the usage would be:
>> public Account : SharedData
>> static SharedPtr<Account> create();
> Do we really need to invent our own template class? Surely this problem has
> been solved in Qt-land before‽
> Can we have some arrangement where we have a typedef or trivial subclass called
> AccountPtr, etc.? Otherwise, we'll have signals like
> accountValidityChanged(bool, Telepathy::SharedPtr<Telepathy::Client::Account>)
> which is horrible! Using Telepathy::Client::AccountPtr is still quite verbose,
> but I think it's the best we're going to get.
The biggest problem here is that you can't forward declare typedefs, so
that would be quite difficult.
You could declare typedef AccountPtr on account.h and typedef
AccountManagerPtr on account-manager.h and both headers have to include
the other, so this wouldn't work.
1 - Have a header that defines all XXXPtr typedefs.
2 - Instead of using typedefs making the XXXPtr a class inherited from
QExplicitlySharedDataPointer<XXX> and forward declare it.
3 - Do not use typedefs at all, always use
QExplicitlySharedDataPointer<XXX> or SharedPtr<XXX> as I did.
4 - ???
More information about the telepathy