From: khizmax Date: Fri, 11 Mar 2016 21:56:41 +0000 (+0300) Subject: Extend urcu::raw_ptr move assignment X-Git-Tag: v2.2.0~367 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=92a4232aaef2ea1a3857db30a941f04e696bab4f;p=libcds.git Extend urcu::raw_ptr move assignment --- 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; }