diff options
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; |