summaryrefslogtreecommitdiff
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qcontiguouscache.h7
-rw-r--r--src/corelib/tools/qlocale.cpp5
-rw-r--r--src/corelib/tools/qregexp.cpp4
-rw-r--r--src/corelib/tools/qshareddata.cpp2
-rw-r--r--src/corelib/tools/qsharedpointer.cpp23
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h97
-rw-r--r--src/corelib/tools/qvector.h4
-rw-r--r--src/corelib/tools/tools.pri2
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