diff options
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qcontiguouscache.h | 7 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 5 | ||||
-rw-r--r-- | src/corelib/tools/qregexp.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qshareddata.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 23 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 97 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 4 | ||||
-rw-r--r-- | src/corelib/tools/tools.pri | 2 |
8 files changed, 102 insertions, 42 deletions
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 0020d2227a..7221925438 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -44,6 +44,7 @@ #include <QtCore/qatomic.h> #include <limits.h> +#include <new> QT_BEGIN_HEADER @@ -76,6 +77,12 @@ struct QContiguousCacheTypedData int start; int offset; uint sharable : 1; + // uint unused : 31; + + // total is 24 bytes (HP-UX aCC: 40 bytes) + // the next entry is already aligned to 8 bytes + // there will be an 8 byte gap here if T requires 16-byte alignment + // (such as long double on 64-bit platforms, __int128, __float128) T array[1]; }; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index a7cc95bbaa..e66f533ab8 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2647,6 +2647,8 @@ static QString timeZone() # else return QString::fromLocal8Bit(_tzname[1]); # endif +#elif defined(Q_OS_VXWORKS) + return QString(); #else tzset(); return QString::fromLocal8Bit(tzname[1]); @@ -4945,6 +4947,9 @@ static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) #define Bletch 0x10 #define Bndry_mask 0xfffff #define Bndry_mask1 0xfffff +#if defined(LSB) && defined(Q_OS_VXWORKS) +#undef LSB +#endif #define LSB 1 #define Sign_bit 0x80000000 #define Log2P 1 diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index adca703696..8bda634dde 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -688,6 +688,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from, {tools/regexp}{Regular Expression Example} */ +#if defined(Q_OS_VXWORKS) && defined(EOS) +# undef EOS +#endif + const int NumBadChars = 64; #define BadChar(ch) ((ch).unicode() % NumBadChars) diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index 1599a13903..d000c3353c 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE QSharedData is designed to be used with QSharedDataPointer or QExplicitlySharedDataPointer to implement custom \l{implicitly - shared} or \l {explicitly shared} classes. QSharedData provides + shared} or explicitly shared classes. QSharedData provides \l{thread-safe} reference counting. See QSharedDataPointer and QExplicitlySharedDataPointer for details. diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index a1867711d0..8a63d641d5 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -902,6 +902,7 @@ QT_BEGIN_NAMESPACE namespace QtSharedPointer { Q_CORE_EXPORT void internalSafetyCheckAdd(const volatile void *); Q_CORE_EXPORT void internalSafetyCheckRemove(const volatile void *); + Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck(); } /*! @@ -966,6 +967,7 @@ void QtSharedPointer::internalSafetyCheckAdd2(const void *d_ptr, const volatile kp->dPointers.insert(d_ptr, data); kp->dataPointers.insert(ptr, d_ptr); + Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size()); } /*! @@ -990,10 +992,29 @@ void QtSharedPointer::internalSafetyCheckRemove2(const void *d_ptr) Q_ASSERT(it2 != kp->dataPointers.end()); //qDebug("Removing d=%p value=%p", d_ptr, it->pointer); - + // remove entries kp->dataPointers.erase(it2); kp->dPointers.erase(it); + Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size()); +} + +/*! + \internal + Called by the QSharedPointer autotest +*/ +void QtSharedPointer::internalSafetyCheckCleanCheck() +{ +# ifdef QT_BUILD_INTERNAL + KnownPointers *const kp = knownPointers(); + Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!"); + + if (kp->dPointers.size() != kp->dataPointers.size()) + qFatal("Internal consistency error: the number of pointers is not equal!"); + + if (!kp->dPointers.isEmpty()) + qFatal("Pointer cleaning failed: %d entries remaining", kp->dPointers.size()); +# endif } QT_END_NAMESPACE diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 657c45aa89..9a5532c86f 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -100,20 +100,22 @@ namespace QtSharedPointer { // used in debug mode to verify the reuse of pointers Q_CORE_EXPORT void internalSafetyCheckAdd2(const void *, const volatile void *); Q_CORE_EXPORT void internalSafetyCheckRemove2(const void *); - + template <class T, typename Klass, typename RetVal> inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)()) { (t->*memberDeleter)(); } template <class T, typename Deleter> inline void executeDeleter(T *t, Deleter d) { d(t); } + template <class T> inline void normalDeleter(T *t) { delete t; } + + // this uses partial template specialization + // the only compilers that didn't support this were MSVC 6.0 and 2002 + template <class T> struct RemovePointer; + template <class T> struct RemovePointer<T *> { typedef T Type; }; + template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; }; + template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; }; - // - // Depending on its template parameter, QSharedPointer derives from either - // QtSharedPointer::InternalRefCount or from QtSharedPointer::ExternalRefCount. - // Both of these classes derive from QtSharedPointer::Basic, which provides common - // operations, - // template <class T> class Basic { @@ -174,6 +176,7 @@ namespace QtSharedPointer { virtual inline bool destroy() { return false; } }; + // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit) template <class T, typename Deleter> struct CustomDeleter @@ -183,6 +186,9 @@ namespace QtSharedPointer { inline CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {} }; + // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*) + // for Deleter = function pointer: 8 (32-bit) / 16 (64-bit) + // for Deleter = PMF: 12 (32-bit) / 24 (64-bit) (GCC) struct ExternalRefCountWithDestroyFn: public ExternalRefCountData { @@ -196,6 +202,7 @@ namespace QtSharedPointer { inline bool destroy() { destroyer(this); return true; } inline void operator delete(void *ptr) { ::operator delete(ptr); } }; + // sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit) template <class T, typename Deleter> struct ExternalRefCountWithCustomDeleter: public ExternalRefCountWithDestroyFn @@ -209,11 +216,23 @@ namespace QtSharedPointer { { Self *realself = static_cast<Self *>(self); executeDeleter(realself->extra.ptr, realself->extra.deleter); + + // delete the deleter too + realself->extra.~Next(); + } + static void safetyCheckDeleter(ExternalRefCountData *self) + { + internalSafetyCheckRemove2(self); + deleter(self); } static inline Self *create(T *ptr, Deleter userDeleter) { +# 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 @@ -240,10 +259,19 @@ namespace QtSharedPointer { static_cast<ExternalRefCountWithContiguousData *>(self); that->data.~T(); } + static void safetyCheckDeleter(ExternalRefCountData *self) + { + internalSafetyCheckRemove2(self); + deleter(self); + } static inline ExternalRefCountData *create(T **ptr) { +# ifdef QT_SHAREDPOINTER_TRACK_POINTERS + DestroyerFn destroy = &safetyCheckDeleter; +# else DestroyerFn destroy = &deleter; +# endif ExternalRefCountWithContiguousData *d = static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData))); @@ -264,9 +292,9 @@ namespace QtSharedPointer { template <class T> class ExternalRefCount: public Basic<T> { - typedef ExternalRefCountData Data; - typedef void (*DeleterFunction)(T *); protected: + typedef ExternalRefCountData Data; + inline void ref() const { d->weakref.ref(); d->strongref.ref(); } inline bool deref() { @@ -278,32 +306,34 @@ namespace QtSharedPointer { inline void internalConstruct(T *ptr) { - Basic<T>::internalConstruct(ptr); +#ifdef QT_SHAREDPOINTER_TRACK_POINTERS + internalConstruct<void (*)(T *)>(ptr, normalDeleter); +#else Q_ASSERT(!d); if (ptr) d = new Data; -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - if (ptr) internalSafetyCheckAdd2(d, ptr); + internalFinishConstruction(ptr); #endif } template <typename Deleter> inline void internalConstruct(T *ptr, Deleter deleter) { - Basic<T>::internalConstruct(ptr); Q_ASSERT(!d); if (ptr) d = ExternalRefCountWithCustomDeleter<T, Deleter>::create(ptr, deleter); -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - if (ptr) internalSafetyCheckAdd2(d, ptr); -#endif + internalFinishConstruction(ptr); } inline void internalCreate() { T *ptr; d = ExternalRefCountWithContiguousData<T>::create(&ptr); + Basic<T>::internalConstruct(ptr); + } + inline void internalFinishConstruction(T *ptr) + { Basic<T>::internalConstruct(ptr); #ifdef QT_SHAREDPOINTER_TRACK_POINTERS if (ptr) internalSafetyCheckAdd2(d, ptr); @@ -323,9 +353,6 @@ namespace QtSharedPointer { inline void internalDestroy() { -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - internalSafetyCheckRemove2(d); -#endif if (!d->destroy()) delete this->value; } @@ -343,12 +370,22 @@ namespace QtSharedPointer { inline void internalSet(Data *o, T *actual) { if (d == o) return; - if (o && !o->strongref) - o = 0; if (o) { Basic<T>::verifyReconstruction(actual); - o->weakref.ref(); - o->strongref.ref(); + + // increase the strongref, but never up from zero + register int tmp = o->strongref; + while (tmp > 0) { + // try to increment from "tmp" to "tmp + 1" + if (o->strongref.testAndSetRelaxed(tmp, tmp + 1)) + break; // succeeded + tmp = o->strongref; // failed, try again + } + + if (tmp) + o->weakref.ref(); + else + o = 0; } if (d && !deref()) delete d; @@ -356,9 +393,7 @@ namespace QtSharedPointer { this->value = d && d->strongref ? actual : 0; } -#if defined(QT_BUILD_INTERNAL) - public: -#endif + protected: Data *d; private: @@ -448,6 +483,7 @@ public: // now initialize the data new (result.data()) T(); + result.internalFinishConstruction(result.data()); return result; } }; @@ -681,14 +717,6 @@ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer< return qSharedPointerObjectCast<X>(src.toStrongRef()); } -# ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION -namespace QtSharedPointer { - template <class T> struct RemovePointer; - template <class T> struct RemovePointer<T *> { typedef T Type; }; - template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; }; - template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; }; -} - template <class X, class T> inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type> qobject_cast(const QSharedPointer<T> &src) @@ -701,7 +729,6 @@ qobject_cast(const QWeakPointer<T> &src) { return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src); } -# endif #endif diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 247f9f1915..3a7b35ce90 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -253,11 +253,7 @@ public: typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; -#ifndef QT_NO_STL typedef ptrdiff_t difference_type; -#else - typedef int difference_type; -#endif typedef iterator Iterator; typedef const_iterator ConstIterator; typedef int size_type; diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 85d9dbf670..e6c6169122 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -114,4 +114,4 @@ HEADERS += tools/qharfbuzz_p.h INCLUDEPATH += ../3rdparty/md5 \ ../3rdparty/md4 -!macx-icc:unix:!symbian:LIBS += -lm +!macx-icc:unix:!symbian:!vxworks:LIBS += -lm |