Keep the #ifdef for tracking shared pointers in a single function

If we have it in different functions, then different out-of-line
implementations could be selected for each object file, resulting in
invalid states. The error I caught was when wrapper.cpp was compiled
without tracking and, therefore, did not place a call to
internalSafetyCheckAdd. However, it called an out-of-line copy of
QtSharedPointer::ExternalRefCountWithCustomDeleter::create, which did
set the deleter to remove the safety check.

Therefore, keep everything in one function.

Change-Id: Ib2c6a606699db49d102704bccdd331ec22a8bd78
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
Thiago Macieira 2012-06-11 13:38:41 +02:00 committed by Qt by Nokia
parent 48b38fb2b0
commit 08b3aceffe

View File

@ -200,18 +200,13 @@ namespace QtSharedPointer {
deleter(self); deleter(self);
} }
static inline Self *create(T *ptr, Deleter userDeleter) static inline Self *create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter)
{ {
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
DestroyerFn destroy = &safetyCheckDeleter;
# else
DestroyerFn destroy = &deleter;
# endif
Self *d = static_cast<Self *>(::operator new(sizeof(Self))); Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
// initialize the two sub-objects // initialize the two sub-objects
new (&d->extra) CustomDeleter(ptr, userDeleter); new (&d->extra) CustomDeleter(ptr, userDeleter);
new (d) BaseClass(destroy); // can't throw new (d) BaseClass(actualDeleter); // can't throw
return d; return d;
} }
@ -244,13 +239,8 @@ namespace QtSharedPointer {
deleter(self); deleter(self);
} }
static inline ExternalRefCountData *create(T **ptr) static inline ExternalRefCountData *create(T **ptr, DestroyerFn destroy)
{ {
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
DestroyerFn destroy = &safetyCheckDeleter;
# else
DestroyerFn destroy = &deleter;
# endif
ExternalRefCountWithContiguousData *d = ExternalRefCountWithContiguousData *d =
static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData))); static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
@ -379,12 +369,21 @@ public:
static inline QSharedPointer<T> create() static inline QSharedPointer<T> create()
{ {
typedef QtSharedPointer::ExternalRefCountWithContiguousData<T> Private;
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
# else
typename Private::DestroyerFn destroy = &Private::deleter;
# endif
QSharedPointer<T> result(Qt::Uninitialized); QSharedPointer<T> result(Qt::Uninitialized);
result.d = QtSharedPointer::ExternalRefCountWithContiguousData<T>::create(&result.value); result.d = Private::create(&result.value, destroy);
// now initialize the data // now initialize the data
new (result.data()) T(); new (result.data()) T();
result.internalFinishConstruction(result.data()); result.d->setQObjectShared(result.value, true);
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
internalSafetyCheckAdd(result.d, result.value);
# endif
return result; return result;
} }
@ -406,18 +405,22 @@ private:
template <typename Deleter> template <typename Deleter>
inline void internalConstruct(T *ptr, Deleter deleter) inline void internalConstruct(T *ptr, Deleter deleter)
{ {
if (ptr) if (!ptr) {
d = QtSharedPointer::ExternalRefCountWithCustomDeleter<T, Deleter>::create(ptr, deleter);
else
d = 0; d = 0;
internalFinishConstruction(ptr); return;
} }
typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<T, Deleter> Private;
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
typename Private::DestroyerFn actualDeleter = &Private::safetyCheckDeleter;
# else
typename Private::DestroyerFn actualDeleter = &Private::deleter;
# endif
d = Private::create(ptr, deleter, actualDeleter);
inline void internalFinishConstruction(T *ptr)
{
d->setQObjectShared(ptr, true); d->setQObjectShared(ptr, true);
#ifdef QT_SHAREDPOINTER_TRACK_POINTERS #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
if (ptr) internalSafetyCheckAdd(d, ptr); internalSafetyCheckAdd(d, ptr);
#endif #endif
} }