| 268 | |
| 269 | template< class T > |
| 270 | bool ThreadSafeRef< T >::trySetFromTo( T* oldVal, T* const volatile& newVal, ETag tag ) |
| 271 | { |
| 272 | bool setTag = false; |
| 273 | bool getTag = false; |
| 274 | bool isTagged = isTaggedPtr( oldVal ); |
| 275 | |
| 276 | switch( tag ) |
| 277 | { |
| 278 | case TAG_PreserveOld: setTag = isTaggedPtr( oldVal ); break; |
| 279 | case TAG_PreserveNew: setTag = isTaggedPtr( newVal ); break; |
| 280 | case TAG_Set: setTag = true; break; |
| 281 | case TAG_Unset: setTag = false; break; |
| 282 | case TAG_SetOrFail: setTag = true; getTag = true; break; |
| 283 | case TAG_UnsetOrFail: setTag = false; getTag = true; break; |
| 284 | case TAG_FailIfSet: if( isTagged ) return false; break; |
| 285 | case TAG_FailIfUnset: if( !isTagged ) return false; break; |
| 286 | } |
| 287 | |
| 288 | T* newValPtr = ( setTag |
| 289 | ? getTaggedPtr( ThreadSafeRefCount< T >::safeRead( newVal ) ) |
| 290 | : getUntaggedPtr( ThreadSafeRefCount< T >::safeRead( newVal ) ) ); |
| 291 | |
| 292 | if( dCompareAndSwap( mPtr, |
| 293 | ( getTag |
| 294 | ? ( setTag |
| 295 | ? getUntaggedPtr( oldVal ) |
| 296 | : getTaggedPtr( oldVal ) ) |
| 297 | : oldVal ), |
| 298 | newValPtr ) ) |
| 299 | { |
| 300 | if( getUntaggedPtr( oldVal ) ) |
| 301 | getUntaggedPtr( oldVal )->release(); |
| 302 | return true; |
| 303 | } |
| 304 | else |
| 305 | { |
| 306 | if( getUntaggedPtr( newValPtr ) ) |
| 307 | getUntaggedPtr( newValPtr )->release(); |
| 308 | return false; |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | template< class T > |
| 313 | inline bool ThreadSafeRef< T >::trySetFromTo( T* oldVal, const ThisType& newVal, ETag tag ) |