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);
}
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)));
// initialize the two sub-objects
new (&d->extra) CustomDeleter(ptr, userDeleter);
new (d) BaseClass(destroy); // can't throw
new (d) BaseClass(actualDeleter); // can't throw
return d;
}
@ -244,13 +239,8 @@ namespace QtSharedPointer {
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 =
static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
@ -379,12 +369,21 @@ public:
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);
result.d = QtSharedPointer::ExternalRefCountWithContiguousData<T>::create(&result.value);
result.d = Private::create(&result.value, destroy);
// now initialize the data
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;
}
@ -406,18 +405,22 @@ private:
template <typename Deleter>
inline void internalConstruct(T *ptr, Deleter deleter)
{
if (ptr)
d = QtSharedPointer::ExternalRefCountWithCustomDeleter<T, Deleter>::create(ptr, deleter);
else
if (!ptr) {
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);
#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
if (ptr) internalSafetyCheckAdd(d, ptr);
internalSafetyCheckAdd(d, ptr);
#endif
}