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:
parent
48b38fb2b0
commit
08b3aceffe
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user