From 8fbdc06643984381d2c9c580a9b2a461c841c78b Mon Sep 17 00:00:00 2001 From: khizmax Date: Sat, 18 Jul 2015 16:37:11 +0300 Subject: [PATCH] Fixed a bug in MichaelList::extract function --- cds/intrusive/michael_list_rcu.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cds/intrusive/michael_list_rcu.h b/cds/intrusive/michael_list_rcu.h index c8f80303..85d3542b 100644 --- a/cds/intrusive/michael_list_rcu.h +++ b/cds/intrusive/michael_list_rcu.h @@ -232,6 +232,8 @@ namespace cds { namespace intrusive { bool unlink_node( position& pos, erase_node_mask nMask ) { + assert(gc::is_locked() ); + // Mark the node (logical deletion) marked_node_ptr next(pos.pNext, 0); @@ -239,7 +241,7 @@ namespace cds { namespace intrusive { // Try physical removal - fast path marked_node_ptr cur(pos.pCur); - if ( pos.pPrev->compare_exchange_strong(cur, marked_node_ptr(pos.pNext), memory_model::memory_order_acquire, atomics::memory_order_relaxed) ) { + if ( pos.pPrev->compare_exchange_strong(cur, marked_node_ptr(pos.pNext), memory_model::memory_order_acquire, atomics::memory_order_relaxed )) { if ( nMask == erase_mask ) link_to_remove_chain( pos, pos.pCur ); } @@ -970,18 +972,23 @@ namespace cds { namespace intrusive { back_off bkoff; assert( !gc::is_locked() ) ; // RCU must not be locked!!! + node_type * pExtracted; { rcu_lock l; for (;;) { if ( !search( refHead, val, pos, cmp ) ) return nullptr; + // store pCur since it may be changed by unlink_node() slow path + pExtracted = pos.pCur; if ( !unlink_node( pos, extract_mask )) { bkoff(); continue; } --m_ItemCounter; - return node_traits::to_value_ptr( pos.pCur ); + value_type * pRet = node_traits::to_value_ptr( pExtracted ); + assert( pRet->m_pDelChain == nullptr ); + return pRet; } } } -- 2.34.1