Просмотр исходного кода

AutoPtr: do 'duplicate' before 'release' (#4068)

Common knowledge in reference counting is "on assignment increment first
then decrement", because "just to be deleted" object could hold last
reference to "just to be assigned" one.

Fixes #3979
Sokolov Yura 2 лет назад
Родитель
Сommit
904075e1f1
1 измененных файлов с 6 добавлено и 17 удалено
  1. 6 17
      Foundation/include/Poco/AutoPtr.h

+ 6 - 17
Foundation/include/Poco/AutoPtr.h

@@ -110,34 +110,23 @@ public:
 	{
 		if (_ptr != ptr)
 		{
-			if (_ptr) _ptr->release();
-			_ptr = ptr;
-			if (shared && _ptr) _ptr->duplicate();
+			if (shared && ptr) ptr->duplicate();
+			std::swap(_ptr, ptr);
+			if (ptr) ptr->release();
 		}
 		return *this;
 	}
 
 	AutoPtr& assign(const AutoPtr& ptr)
 	{
-		if (&ptr != this)
-		{
-			if (_ptr) _ptr->release();
-			_ptr = ptr._ptr;
-			if (_ptr) _ptr->duplicate();
-		}
-		return *this;
+		return assign(ptr._ptr, true);
 	}
 
 	template <class Other>
 	AutoPtr& assign(const AutoPtr<Other>& ptr)
 	{
-		if (ptr.get() != _ptr)
-		{
-			if (_ptr) _ptr->release();
-			_ptr = const_cast<Other*>(ptr.get());
-			if (_ptr) _ptr->duplicate();
-		}
-		return *this;
+		C* nptr = const_cast<Other*>(ptr.get());
+		return assign(nptr, true);
 	}
 
 	void reset()