Fixed serious bug in MichaelSet::emplace() function
authorkhizmax <libcds.dev@gmail.com>
Thu, 17 Mar 2016 19:49:22 +0000 (22:49 +0300)
committerkhizmax <libcds.dev@gmail.com>
Thu, 17 Mar 2016 19:49:22 +0000 (22:49 +0300)
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.

cds/container/impl/lazy_list.h
cds/container/lazy_list_nogc.h
cds/container/lazy_list_rcu.h

index 45ddb68e35ea40d102d1340635eee682ecdb7fe8..541f2453fd06abe3a9330812305bc9b305d11dd3 100644 (file)
@@ -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<node_type, value_type> > 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 <typename Q>
         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 );
index 2ffe636c5310ebb9a8aa4a06c5fee25bc4d7add7..469159d62bc529f4391bf0a8e952f3dca43a2469 100644 (file)
@@ -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 );
index 2d08ef03688ee500e7e749db5f762869a8550139..b900a7a2ba951cfb2dbc5f6075d9fa3ae61fb5d9 100644 (file)
@@ -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 <typename Q>
         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 );