diff --git a/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs b/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs index bb8c4f50f12c21..1ae27b2ba0a8ac 100644 --- a/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs +++ b/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs @@ -322,18 +322,19 @@ impl ReceiveAndBuffer for TransactionViewReceiveAndBuffer { let start = Instant::now(); let mut received_message = false; - // If not leader, do a blocking-receive initially. This lets the thread - // sleep when there is not work to do. - // TODO: Is it better to manually sleep instead, avoiding the locking - // overhead for wakers? But then risk not waking up when message - // received - as long as sleep is somewhat short, this should be - // fine. - if matches!( - decision, - BufferedPacketsDecision::Forward - | BufferedPacketsDecision::ForwardAndHold - | BufferedPacketsDecision::Hold - ) { + // If not leader/unknown, do a blocking-receive initially. This lets + // the thread sleep until a message is received, or until the timeout. + // Additionally, only sleep if the container is empty. + if container.is_empty() + && matches!( + decision, + BufferedPacketsDecision::Forward | BufferedPacketsDecision::ForwardAndHold + ) + { + // TODO: Is it better to manually sleep instead, avoiding the locking + // overhead for wakers? But then risk not waking up when message + // received - as long as sleep is somewhat short, this should be + // fine. match self.receiver.recv_timeout(TIMEOUT) { Ok(packet_batch_message) => { received_message = true;