From: khizmax Date: Thu, 17 Mar 2016 19:49:22 +0000 (+0300) Subject: Fixed serious bug in MichaelSet::emplace() function X-Git-Tag: v2.2.0~340 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fa32cf17b6f47caa89d15bd5eff197f68e0b4c2d;p=libcds.git Fixed serious bug in MichaelSet::emplace() function New node was created twice from the arguments by move semantics. However, move semantics may change internal state of the argument. This can lead to an incorrect element in the set and even to an incorrect key that breaks the set logic. --- diff --git a/cds/container/impl/lazy_list.h b/cds/container/impl/lazy_list.h index 45ddb68e..541f2453 100644 --- a/cds/container/impl/lazy_list.h +++ b/cds/container/impl/lazy_list.h @@ -157,20 +157,18 @@ namespace cds { namespace container { /// Guarded pointer typedef typename gc::template guarded_ptr< node_type, value_type, details::guarded_ptr_cast_set > guarded_ptr; - private: + protected: //@cond static value_type& node_to_value( node_type& n ) { return n.m_Value; } + static value_type const& node_to_value( node_type const& n ) { return n.m_Value; } - //@endcond - protected: - //@cond template static node_type * alloc_node( Q const& v ) { @@ -756,6 +754,11 @@ namespace cds { namespace container { protected: //@cond + bool insert_node( node_type * pNode ) + { + return insert_node_at( head(), pNode ); + } + bool insert_node_at( head_type& refHead, node_type * pNode ) { assert( pNode != nullptr ); diff --git a/cds/container/lazy_list_nogc.h b/cds/container/lazy_list_nogc.h index 2ffe636c..469159d6 100644 --- a/cds/container/lazy_list_nogc.h +++ b/cds/container/lazy_list_nogc.h @@ -96,6 +96,11 @@ namespace cds { namespace container { protected: //@cond + static value_type& node_to_value( node_type& n ) + { + return n.m_Value; + } + static node_type * alloc_node() { return cxx_allocator().New(); @@ -441,6 +446,11 @@ namespace cds { namespace container { protected: //@cond + iterator insert_node( node_type * pNode ) + { + return node_to_iterator( insert_node_at( head(), pNode )); + } + node_type * insert_node_at( head_type& refHead, node_type * pNode ) { assert( pNode != nullptr ); diff --git a/cds/container/lazy_list_rcu.h b/cds/container/lazy_list_rcu.h index 2d08ef03..b900a7a2 100644 --- a/cds/container/lazy_list_rcu.h +++ b/cds/container/lazy_list_rcu.h @@ -161,20 +161,18 @@ namespace cds { namespace container { /// Type of \p get() member function return value typedef value_type * raw_ptr; - private: + protected: //@cond static value_type& node_to_value( node_type& n ) { return n.m_Value; } + static value_type const& node_to_value( node_type const& n ) { return n.m_Value; } - //@endcond - protected: - //@cond template static node_type * alloc_node( Q const& v ) { @@ -772,6 +770,11 @@ namespace cds { namespace container { protected: //@cond + bool insert_node( node_type * pNode ) + { + return insert_node_at( head(), pNode ); + } + bool insert_node_at( head_type& refHead, node_type * pNode ) { assert( pNode != nullptr );