private E xfer ( E e , boolean haveData , int how , long nanos ) { if ( haveData && ( e == null ) ) throw new NullPointerException ( ) ; Node s = null ; // the node to append, if needed retry : for ( ; ; ) { // restart on append race for ( Node h = head , p = h ; p != null ; ) { // find & match first node boolean isData = p . isData ; Object item = p . item ; if ( item != FORGOTTEN && ( item != null ) == isData ) { // unmatched if ( isData == haveData ) // can't match break ; if ( p . casItem ( item , e ) ) { // match for ( Node q = p ; q != h ; ) { Node n = q . next ; // update by 2 unless singleton if ( head == h && casHead ( h , n == null ? q : n ) ) { h . forgetNext ( ) ; break ; } // advance and retry if ( ( h = head ) == null || ( q = h . next ) == null || ! q . isMatched ( ) ) break ; // unless slack < 2 } LockSupport . unpark ( p . waiter ) ; @ SuppressWarnings ( "unchecked" ) E itemE = ( E ) item ; return itemE ; } } Node n = p . next ; p = ( UNLINKED != n ) ? n : ( h = head ) ; // Use head if p offlist } if ( how != NOW ) { // No matches available if ( s == null ) s = new Node ( e , haveData ) ; Node pred = tryAppend ( s , haveData ) ; if ( pred == null ) continue retry ; // lost race vs opposite mode if ( how != ASYNC ) return awaitMatch ( s , pred , e , ( how == TIMED ) , nanos ) ; } return e ; // not waiting } }
Implements all queuing methods . See above for explanation .