[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 
GObjects world.
> 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
>> {
>> public:
>> ...
>> 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.
>
>     S
>   
>   
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.

Solutions:
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 - ???

BR
Andrunko


More information about the telepathy mailing list