bugfix in cds::gc::HP::guarded_ptr
[libcds.git] / cds / gc / impl / hp_decl.h
index 72de7d0e78a6338fe861913fcb83feaa3d2115d6..bffc52687ad8139178050d7d72aee4dc9b13dbff 100644 (file)
@@ -444,13 +444,13 @@ namespace cds { namespace gc {
 
             //@cond
             /// Initializes guarded pointer with \p p
-            guarded_ptr( guarded_type * p ) CDS_NOEXCEPT
+            explicit guarded_ptr( guarded_type * p ) CDS_NOEXCEPT
             {
                 alloc_guard();
                 assert( m_pGuard );
                 m_pGuard->set(p);
             }
-            guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT
+            explicit guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT
                 : m_pGuard( nullptr )
             {}
             //@endcond
@@ -477,9 +477,16 @@ namespace cds { namespace gc {
             /// Move-assignment operator
             guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT
             {
-                free_guard();
-                m_pGuard = gp.m_pGuard;
-                gp.m_pGuard = nullptr;
+                // Hazard Pointer array is organized as a stack
+                if ( m_pGuard && m_pGuard > gp.m_pGuard ) {
+                    m_pGuard->set( gp.m_pGuard->get(atomics::memory_order_relaxed) );
+                    gp.free_guard();
+                }
+                else {
+                    free_guard();
+                    m_pGuard = gp.m_pGuard;
+                    gp.m_pGuard = nullptr;
+                }
                 return *this;
             }
 
@@ -510,7 +517,7 @@ namespace cds { namespace gc {
             /// Checks if the guarded pointer is \p nullptr
             bool empty() const CDS_NOEXCEPT
             {
-                return !m_pGuard || m_pGuard->get() == nullptr;
+                return !m_pGuard || m_pGuard->get( atomics::memory_order_relaxed ) == nullptr;
             }
 
             /// \p bool operator returns <tt>!empty()</tt>