From dda1ac8e355b4478bc7dd2fb944b5e2962ba94b4 Mon Sep 17 00:00:00 2001 From: daps94 <35882689+daps94@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:06:08 +0700 Subject: [PATCH] perf(mempool): collapse queue Push into single write-lock path Remove the separate isFull() RLock check from Push() and perform the capacity check inside the write lock. This eliminates a TOCTOU window between the capacity check and the actual push, and reduces lock round-trips from two to one per insertion. Co-Authored-By: Claude Opus 4.6 --- mempool/internal/queue/queue.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/mempool/internal/queue/queue.go b/mempool/internal/queue/queue.go index 68eb23c56..3041182fd 100644 --- a/mempool/internal/queue/queue.go +++ b/mempool/internal/queue/queue.go @@ -66,17 +66,17 @@ func (iq *Queue[Tx]) Push(tx *Tx) <-chan error { sub := make(chan error, 1) if tx == nil { - // TODO: when do we expect this to happen? close(sub) return sub } - if iq.isFull() { + + iq.lock.Lock() + if iq.maxSize > 0 && iq.queue.Len() >= iq.maxSize { + iq.lock.Unlock() sub <- ErrQueueFull close(sub) return sub } - - iq.lock.Lock() iq.queue.PushBack(insertItem[Tx]{tx: tx, sub: sub}) iq.lock.Unlock() @@ -168,14 +168,6 @@ func (iq *Queue[Tx]) insertTxs(txs []*Tx) []error { return errs } -// isFull returns true if the queue is at capacity and cannot accept anymore -// Tx's, false otherwise. -func (iq *Queue[Tx]) isFull() bool { - iq.lock.RLock() - defer iq.lock.RUnlock() - return iq.queue.Len() >= iq.maxSize -} - // Close stops the main loop of the queue. func (iq *Queue[Tx]) Close() { close(iq.done)