+
+ private:
+ //@cond
+ bool insert_at_locked( node_type * pHead, value_type& val )
+ {
+ // RCU lock should be locked
+ assert( gc::is_locked());
+
+ position pos;
+ key_comparator cmp;
+
+ while ( true ) {
+ search( pHead, val, pos );
+ {
+ scoped_position_lock alp( pos );
+ if ( validate( pos.pPred, pos.pCur )) {
+ if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) {
+ // failed: key already in list
+ m_Stat.onInsertFailed();
+ return false;
+ }
+
+ link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur );
+ break;
+ }
+ }
+
+ m_Stat.onInsertRetry();
+ }
+
+ ++m_ItemCounter;
+ m_Stat.onInsertSuccess();
+ return true;
+
+ }
+
+ template <typename Func>
+ std::pair<iterator, bool> update_at_locked( node_type * pHead, value_type& val, Func func, bool bAllowInsert )
+ {
+ // RCU lock should be locked
+ assert( gc::is_locked());
+
+ position pos;
+ key_comparator cmp;
+
+ while ( true ) {
+ search( pHead, val, pos );
+ {
+ scoped_position_lock alp( pos );
+ if ( validate( pos.pPred, pos.pCur )) {
+ if ( pos.pCur != &m_Tail && cmp( *node_traits::to_value_ptr( *pos.pCur ), val ) == 0 ) {
+ // key already in the list
+
+ func( false, *node_traits::to_value_ptr( *pos.pCur ), val );
+ m_Stat.onUpdateExisting();
+ return std::make_pair( iterator( pos.pCur ), false );
+ }
+ else {
+ // new key
+ if ( !bAllowInsert ) {
+ m_Stat.onUpdateFailed();
+ return std::make_pair( end(), false );
+ }
+
+ func( true, val, val );
+ link_node( node_traits::to_node_ptr( val ), pos.pPred, pos.pCur );
+ break;
+ }
+ }
+ }
+
+ m_Stat.onUpdateRetry();
+ }
+
+ ++m_ItemCounter;
+ m_Stat.onUpdateNew();
+ return std::make_pair( iterator( node_traits::to_node_ptr( val )), true );
+ }
+ //@endcond
+
+ private:
+ //@cond
+ const_iterator get_const_begin() const
+ {
+ const_iterator it( const_cast<node_type *>(&m_Head));
+ ++it; // skip dummy head
+ return it;
+ }
+ const_iterator get_const_end() const
+ {
+ return const_iterator( const_cast<node_type *>(&m_Tail));
+ }
+ //@endcond