From 92a4232aaef2ea1a3857db30a941f04e696bab4f Mon Sep 17 00:00:00 2001 From: khizmax Date: Sat, 12 Mar 2016 00:56:41 +0300 Subject: [PATCH] Extend urcu::raw_ptr move assignment --- cds/intrusive/details/raw_ptr_disposer.h | 14 +++++++++++--- cds/urcu/raw_ptr.h | 10 +++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/cds/intrusive/details/raw_ptr_disposer.h b/cds/intrusive/details/raw_ptr_disposer.h index 0975d8a7..de03f802 100644 --- a/cds/intrusive/details/raw_ptr_disposer.h +++ b/cds/intrusive/details/raw_ptr_disposer.h @@ -69,15 +69,23 @@ namespace cds { namespace intrusive { namespace details { apply(); } - raw_ptr_disposer& operator=(raw_ptr_disposer&& d) + raw_ptr_disposer& combine(raw_ptr_disposer&& d) { - assert( pReclaimedChain == nullptr ); - pReclaimedChain = d.pReclaimedChain; + if ( pReclaimedChain == nullptr ) + pReclaimedChain = d.pReclaimedChain; + else if ( d.pReclaimedChain ) { + // union reclaimed chains + node_type * pEnd = d.pReclaimedChain; + for ( ; pEnd->m_pDelChain; pEnd = pEnd->m_pDelChain ); + pEnd->m_pDelChain = pReclaimedChain; + pReclaimedChain = d.pReclaimedChain; + } d.pReclaimedChain = nullptr; return *this; } raw_ptr_disposer& operator=(raw_ptr_disposer const& d) = delete; + raw_ptr_disposer& operator=( raw_ptr_disposer&& d ) = delete; void apply() { diff --git a/cds/urcu/raw_ptr.h b/cds/urcu/raw_ptr.h index 374ac81d..c277edfe 100644 --- a/cds/urcu/raw_ptr.h +++ b/cds/urcu/raw_ptr.h @@ -47,7 +47,7 @@ namespace cds { namespace urcu { outside RCU lock. The object of \p %raw_ptr solves that problem: it contains the pointer to the node found - and a chain of nodes that were reclaimed during traversing. The \p %raw_ptr object destructor + and a chain of nodes that were be reclaimed during traversing. The \p %raw_ptr object destructor frees the chain (but not the node found) passing it to RCU \p batch_retire(). The object of \p %raw_ptr class must be destructed only outside RCU-lock of current thread. @@ -136,16 +136,12 @@ namespace cds { namespace urcu { /// Move assignment operator /** This operator may be called only inside RCU-lock. - The \p this should be empty. */ raw_ptr& operator=( raw_ptr&& p ) CDS_NOEXCEPT { - assert( empty() ); - if ( !rcu::is_locked() ) - release(); - + assert( rcu::is_locked()); m_ptr = p.m_ptr; - m_Enum = std::move( p.m_Enum ); + m_Enum.combine( std::move( p.m_Enum )); p.m_ptr = nullptr; return *this; } -- 2.34.1