summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOssama Othman <ossama-othman@users.noreply.github.com>2006-02-23 18:46:42 +0000
committerOssama Othman <ossama-othman@users.noreply.github.com>2006-02-23 18:46:42 +0000
commit78a83b6f1ca8bfe8cc7eb66564e325450cb66db2 (patch)
tree847bd6781f595c481da5ca6aabf77ac38dff5104
parent7d78d12ada9aebd9006a33fd8a0f0292924d60af (diff)
downloadATCD-78a83b6f1ca8bfe8cc7eb66564e325450cb66db2.tar.gz
ChangeLogTag:Thu Feb 23 18:41:18 UTC 2006 Ossama Othman <ossama_othman at symantec dot com>
-rw-r--r--TAO/ChangeLog13
-rw-r--r--TAO/tao/Utils/Servant_Var.inl24
-rw-r--r--TAO/tao/Valuetype/Value_VarOut_T.cpp11
3 files changed, 42 insertions, 6 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 76dd34ce2d9..86b6aa25942 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,16 @@
+Thu Feb 23 18:41:18 UTC 2006 Ossama Othman <ossama_othman at symantec dot com>
+
+ * tao/Utils/Servant_Var.inl (operator=):
+ * tao/Valuetype/Value_VarOut_T.cpp (operator=):
+
+ Fixed problem where non-copying assignment prematurely decreased
+ reference count on contained object by adding a check for
+ self-assignment. The canonical copy-and-swap idiom was used to
+ provide a strong exception safety guarantee. It doesn't require
+ a self-assignment check for copying assignment but it may be
+ needed for non-copying assignment. Addresses memory access
+ violations.
+
Thu Feb 23 17:14:25 UTC 2006 Simon McQueen <sm@prismtech.com>
* tao/GIOP_Message_Lite.cpp:
diff --git a/TAO/tao/Utils/Servant_Var.inl b/TAO/tao/Utils/Servant_Var.inl
index 6396237bc9c..da2ff1d6e95 100644
--- a/TAO/tao/Utils/Servant_Var.inl
+++ b/TAO/tao/Utils/Servant_Var.inl
@@ -64,8 +64,16 @@ template <class T>
ACE_INLINE typename TAO::Utils::Servant_Var<T> &
TAO::Utils::Servant_Var<T>::operator= (T * p)
{
- TAO::Utils::Servant_Var<T> tmp (p);
- this->swap (tmp);
+ if (this->ptr_ != p)
+ {
+ // This constructor doesn't increase the reference count so we
+ // we must check for self-assignment. Otherwise the reference
+ // count would be prematurely decremented upon exiting this
+ // scope.
+ TAO::Utils::Servant_Var<T> tmp (p);
+ this->swap (tmp);
+ }
+
return *this;
}
@@ -119,8 +127,16 @@ template <class T> template <class Y>
ACE_INLINE typename TAO::Utils::Servant_Var<T> &
TAO::Utils::Servant_Var<T>::operator= (Y * p)
{
- TAO::Utils::Servant_Var<T> tmp (p);
- this->swap (tmp);
+ if (this->ptr_ != p)
+ {
+ // This constructor doesn't increase the reference count so we
+ // we must check for self-assignment. Otherwise the reference
+ // count would be prematurely decremented upon exiting this
+ // scope.
+ TAO::Utils::Servant_Var<T> tmp (p);
+ this->swap (tmp);
+ }
+
return *this;
}
#endif /* ACE_LACKS_MEMBER_TEMPLATES */
diff --git a/TAO/tao/Valuetype/Value_VarOut_T.cpp b/TAO/tao/Valuetype/Value_VarOut_T.cpp
index 49320b51f77..5e5049b099f 100644
--- a/TAO/tao/Valuetype/Value_VarOut_T.cpp
+++ b/TAO/tao/Valuetype/Value_VarOut_T.cpp
@@ -73,8 +73,15 @@ template <typename T>
TAO_Value_Var_T<T> &
TAO_Value_Var_T<T>::operator= (T * p)
{
- TAO_Value_Var_T<T> tmp (p);
- std::swap (this->ptr_, tmp.ptr_);
+ if (this->ptr_ != p)
+ {
+ // This constructor doesn't increase the reference count so we
+ // we must check for self-assignment. Otherwise the reference
+ // count would be prematurely decremented upon exiting this
+ // scope.
+ TAO_Value_Var_T<T> tmp (p);
+ std::swap (this->ptr_, tmp.ptr_);
+ }
return *this;
}