diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-08-01 09:32:50 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-08-03 12:14:57 (GMT) |
commit | b969da8cf65bdcc00007415caff2dc69a09257c7 (patch) | |
tree | 9ab562cd8bd6627cf08a33a62b423ca9d7b28431 /src | |
parent | 1c5cf2e3d6f091593aec237bbb527cb8cdb964c4 (diff) | |
download | Qt-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.h | 18 |
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; |