[Nepomuk] Nepomuk Core - Questions & Patches
Sebastian Trüg
trueg at kde.org
Mon May 10 14:30:49 CEST 2010
Hi Vishesh,
again and again: thanks a lot for looking over this code!
On 05/10/2010 02:00 PM, Vishesh Handa wrote:
> 9. *ResourceManagerPrivate::cleanUpCache()* : I don't get how this
> works, and for what it's worth it doesn't always work, and I have proof
> that it doesn't (backtrace + debug statements) Look at the added kcrash,
> it has debug statements initially and then the backtrace.
>
> Try to bear with me while I write down a lengthy explanation.
>
> RIP = Resource which is a Proxy for other Resources.
> RHP = Resource which has a Proxy.
> RES = Normal Resource which isn't a RIP or RHP.
>
> If you look at the source code cleanUpCache() -
>
> QList<ResourceData*> rdl = m_uriKickoffData.values() +
> m_idKickoffData.values();
> for( QList<ResourceData*>::iterator rdIt = rdl.begin();
> rdIt != rdl.end(); ++rdIt ) {
> ResourceData* data = *rdIt;
> if ( !data->cnt() ) {
> delete data;
> if( num > 0 && --num == 0 )
> break;
> }
> }
>
> when the loop is running thsese 2 cases can occur (there are many other
> cases, but I don't care about them) -
>
> *1. RIP *followed by a *RHP* :
> Initially the RIP would come, and since its cnt() won't be 0, it would
> not get deleted. Then the RHP (who's proxy is the previous RIP) would
> come, and since its cnt() = 0, it should get deleted. As it's getting
> deleted ResourceData::resetAll() would be called.
>
> // reset proxy
> bool hadProxy = false;
> if( m_proxyData ) {
> kDebug() << "Has proxy data : " << m_proxyData;
> kDebug() << m_proxyData->cnt();
> hadProxy = true;
> if( !m_proxyData->deref() &&
> rm()->dataCacheFull() ) {
> kDebug() << "Deleting proxy data";
> delete m_proxyData;
> }
> kDebug() << m_proxyData->cnt();
> m_proxyData = 0;
> }
>
> (Please ignore the debug statements)
>
> Here the RIP would be deref() and it should NOT get deleted as
> rm()->dataCacheFull() would most probably be false (Just assume it is.)
> The RHP would then get deleted and the RIP still exists, and will
> continue to exist even after cleanUpCache() has finished execution. Look
> at proof.
>
> One way is to loop until m_uriKickoffData and m_idKickoffData are both
> empty.
That would at least be temp solution. Another solution would be to
replace rm->dataCacheFull() with a call that always returns true when
clearing the cache. Although then we could probably not reuse the same
loop to free up a single cache entry.
> *2. RHP *followed by a *RIP*:
> The RHP comes first, gets deleted and deletes the proxy (assume
> dataCacheFull() to be true). Then when the RIP comes along it would test
> itself with /!data->cnt()/, and since data doesn't point to anything
> valid anymore, BOOM!, segfault, and it should crash. Unfortunately I
> haven't been able to prove this!
Indeed. This could be solved the same way as above I assume: the RM does
prevent proxy deletion in cleanup mode.... but might be hacky.
> *Some other stuff :* (Complaints. Just ignore them!)
>
> I find all this proxy stuff kinda confusing. I know it's super helpful,
It is very confusing.
> but it is confusing. I don't like the idea that every ResourceData first
> queries it's proxy, what if the proxy has been deleted? I know that
> can't happen because of the checks, but still. I wonder if QSharedData
> or something like that could be used. I'll try a couple of things, and
> come back later.
I would love to have that improved. Believe it or not: there was a time
when this code was even more confusing. It used to try to handle dirty
caches and sync regularly. A total mess which never worked.
> The ResouceData and ResourceMangerPrivate classes are tightly coupled,
> and it is difficult to track who's managing who's data. For example -
> ResourceManagerPrivate::data is responsible for adding ResourceData to
> the lists (m_initialized and all), however ResourceData:resetAll is
> responsible for removing them. It it wasn't for KDevelop's handy "Show
> uses" features, I would have been, well, frustrated.
You are right. Maybe all resource list handling should be done in
ResourceData.
> I try to look for some kind of solution.
>
> Sorry for the obscenely large mail, and part rant.
these are very constructive rants. So keep em coming. :)
Cheers,
Sebastian
More information about the Nepomuk
mailing list