diff --git a/network/throttling/inbound_conn_upgrade_throttler.go b/network/throttling/inbound_conn_upgrade_throttler.go index 4067d80b2b29..ace53a1fb34b 100644 --- a/network/throttling/inbound_conn_upgrade_throttler.go +++ b/network/throttling/inbound_conn_upgrade_throttler.go @@ -11,6 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" + + timerpkg "github.com/ava-labs/avalanchego/utils/timer" ) var ( @@ -131,10 +133,7 @@ func (n *inboundConnUpgradeThrottler) ShouldUpgrade(addrPort netip.AddrPort) boo } func (n *inboundConnUpgradeThrottler) Dispatch() { - timer := time.NewTimer(0) - if !timer.Stop() { - <-timer.C - } + timer := timerpkg.StoppedTimer() defer timer.Stop() for { diff --git a/network/throttling/inbound_resource_throttler.go b/network/throttling/inbound_resource_throttler.go index eb915e03232c..967af69a47d2 100644 --- a/network/throttling/inbound_resource_throttler.go +++ b/network/throttling/inbound_resource_throttler.go @@ -15,6 +15,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/utils/timer/mockable" + + timerpkg "github.com/ava-labs/avalanchego/utils/timer" ) const epsilon = time.Millisecond @@ -107,11 +109,7 @@ func NewSystemThrottler( timerPool: sync.Pool{ New: func() interface{} { // Satisfy invariant that timer is stopped and drained. - timer := time.NewTimer(0) - if !timer.Stop() { - <-timer.C - } - return timer + return timerpkg.StoppedTimer() }, }, }, nil diff --git a/tests/antithesis/avalanchego/main.go b/tests/antithesis/avalanchego/main.go index ae8f0bb051e8..7c68ed3fbd23 100644 --- a/tests/antithesis/avalanchego/main.go +++ b/tests/antithesis/avalanchego/main.go @@ -31,6 +31,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + timerpkg "github.com/ava-labs/avalanchego/utils/timer" xtxs "github.com/ava-labs/avalanchego/vms/avm/txs" ptxs "github.com/ava-labs/avalanchego/vms/platformvm/txs" xbuilder "github.com/ava-labs/avalanchego/wallet/chain/x/builder" @@ -148,10 +149,7 @@ type workload struct { } func (w *workload) run(ctx context.Context) { - timer := time.NewTimer(0) - if !timer.Stop() { - <-timer.C - } + timer := timerpkg.StoppedTimer() var ( xWallet = w.wallet.X() diff --git a/tests/antithesis/xsvm/main.go b/tests/antithesis/xsvm/main.go index 9e70ebff1fbf..bb59f769127d 100644 --- a/tests/antithesis/xsvm/main.go +++ b/tests/antithesis/xsvm/main.go @@ -23,6 +23,8 @@ import ( "github.com/ava-labs/avalanchego/vms/example/xsvm/api" "github.com/ava-labs/avalanchego/vms/example/xsvm/cmd/issue/status" "github.com/ava-labs/avalanchego/vms/example/xsvm/cmd/issue/transfer" + + timerpkg "github.com/ava-labs/avalanchego/utils/timer" ) const ( @@ -118,10 +120,7 @@ type workload struct { } func (w *workload) run(ctx context.Context) { - timer := time.NewTimer(0) - if !timer.Stop() { - <-timer.C - } + timer := timerpkg.StoppedTimer() uri := w.uris[w.id%len(w.uris)] diff --git a/utils/timer/stopped_timer.go b/utils/timer/stopped_timer.go new file mode 100644 index 000000000000..1777c830e6e3 --- /dev/null +++ b/utils/timer/stopped_timer.go @@ -0,0 +1,24 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package timer + +import "time" + +// StoppedTimer returns a stopped timer so that there is no entry on +// the C channel (and there isn't one scheduled to be added). +// +// This means that after calling Reset there will be no events on the +// channel until the timer fires (at which point there will be exactly +// one event sent to the channel). +// +// It enables re-using the timer across loop iterations without +// needing to have the first loop iteration perform any == nil checks +// to initialize the first invocation. +func StoppedTimer() *time.Timer { + timer := time.NewTimer(0) + if !timer.Stop() { + <-timer.C + } + return timer +}