summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-08-01 09:32:50 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2009-08-03 12:14:57 (GMT)
commitb969da8cf65bdcc00007415caff2dc69a09257c7 (patch)
tree9ab562cd8bd6627cf08a33a62b423ca9d7b28431 /src
parent1c5cf2e3d6f091593aec237bbb527cb8cdb964c4 (diff)
downloadQt-b969da8cf65bdcc00007415caff2dc69a09257c7.zip
Qt-b969da8cf65bdcc00007415caff2dc69a09257c7.tar.gz
Qt-b969da8cf65bdcc00007415caff2dc69a09257c7.tar.bz2
Ensure that we never increase the strong reference count up from zero.
Also add some thread stress tests to try and detect doing it wrong. Reviewed-By: Bradley T. Hughes
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index b5daf5d..9fa8df4 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -364,12 +364,22 @@ namespace QtSharedPointer {
inline void internalSet(Data *o, T *actual)
{
if (d == o) return;
- if (o && !o->strongref)
- o = 0;
if (o) {
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;