It is often stated that dereferencing a smart pointer does not have notable performance impacts. (For example here: C Smart Pointer Performance)
I am now wondering if this is really true. I understand that it could be, if operations on the object referenced are atomic.
Thinking of code based on this snippets:
class Worker
{
[...]
public:
void setDataProvider( shared_ptr<DataProvider> p )
{
m_provider = p;
}
void doWork()
{
[...]
for(;;) {
int d = m_provider->getSomeData();
[ do something with d ]
}
}
private:
shared_ptr<DataProvider> m_provider;
};
doWork()
will be permanently executed, and from time to time setDataProvider()
is called from a second thread. Quite a normal smart pointer usage scenario.
Common consensus says that setDataProvider()
has some extra costs, as the lock-protected refcount has to be changed, but m_provider->getSomeData()
hasn't. It is said to be comparable to normal pointer dereferencing, at least no costly locking is needed.
But how can that work? Lets assume, getSomeData()
is not an atomic operation, it might have some logic and a notable execution time.
How is *m_provider
protected from being deleted while getSomeData()
is executed? The class might be the only owner of the object. Overwriting m_provider
will lower the pointer's refcount by one. Either m_provider->getSomeData()
temporarily has to raise the refcount, or the object is being protected from deletion otherwise while getSomeData()
runs.
In both cases some costly synchronization/locking mechanism is needed.
addendum: I used the standard shared_ptr
in the example, as I am wondering about this in general. However the real code uses QSharedPointer
so I am specially interested about this. I naively assumed both would have the same thread safety, which might be wrong.