synchronized void offer ( TransactionTask task ) { Iv2Trace . logTransactionTaskQueueOffer ( task ) ; TransactionState txnState = task . getTransactionState ( ) ; if ( ! m_backlog . isEmpty ( ) ) { /* * This branch happens during regular execution when a multi-part is in progress. * The first task for the multi-part is the head of the queue, and all the single parts * are being queued behind it. The txnid check catches tasks that are part of the multi-part * and immediately queues them for execution. If any multi-part txn with smaller txnId shows up, * it must from repair process, just let it through. */ if ( txnState . isSinglePartition ( ) ) { m_backlog . addLast ( task ) ; return ; } //It is possible a RO MP read with higher TxnId could be executed before a RO MP reader with lower TxnId //so do not offer them to the site task queue in the same time, place it in the backlog instead. However, //if it is an MP Write with a lower TxnId than the TxnId at the head of the backlog it could be a repair //task so put the MP Write task into the Scoreboard or the SiteTaskQueue TransactionTask headTask = m_backlog . getFirst ( ) ; if ( txnState . isReadOnly ( ) && headTask . getTransactionState ( ) . isReadOnly ( ) ? TxnEgo . getSequence ( task . getTxnId ( ) ) != TxnEgo . getSequence ( headTask . getTxnId ( ) ) : TxnEgo . getSequence ( task . getTxnId ( ) ) > TxnEgo . getSequence ( headTask . getTxnId ( ) ) ) { m_backlog . addLast ( task ) ; } else if ( task . needCoordination ( ) && m_scoreboardEnabled ) { /* * This branch coordinates FragmentTask or CompletedTransactionTask, * holds the tasks until all the sites on the node receive the task. * Task with newer spHandle will */ coordinatedTaskQueueOffer ( task ) ; } else { taskQueueOffer ( task ) ; } } else { /* * Base case nothing queued nothing in progress * If the task is a multipart then put an entry in the backlog which * will act as a barrier for single parts, queuing them for execution after the * multipart */ if ( ! txnState . isSinglePartition ( ) ) { m_backlog . addLast ( task ) ; } /* * This branch coordinates FragmentTask or CompletedTransactionTask, * holds the tasks until all the sites on the node receive the task. * Task with newer spHandle will */ if ( task . needCoordination ( ) && m_scoreboardEnabled ) { coordinatedTaskQueueOffer ( task ) ; } else { taskQueueOffer ( task ) ; } } }
If necessary stick this task in the backlog . Many network threads may be racing to reach here synchronize to serialize queue order