diff --git a/database/ffldb/interface_test.go b/database/ffldb/interface_test.go index 0f0aa9585..728f8d288 100644 --- a/database/ffldb/interface_test.go +++ b/database/ffldb/interface_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2015-2016 The btcsuite developers -// Copyright (c) 2016-2025 The Decred developers +// Copyright (c) 2016-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -2163,17 +2163,17 @@ func testConcurrentClose(tc *testContext) bool { // Start up a few readers and wait for them to acquire views. Each // reader waits for a signal to complete to ensure the transactions stay // open until they are explicitly signalled to be closed. - var activeReaders int32 + var activeReaders atomic.Int32 numReaders := 3 started := make(chan struct{}) finishReaders := make(chan struct{}) resultChan := make(chan bool, numReaders+1) reader := func() { err := tc.db.View(func(tx database.Tx) error { - atomic.AddInt32(&activeReaders, 1) + activeReaders.Add(1) started <- struct{}{} <-finishReaders - atomic.AddInt32(&activeReaders, -1) + activeReaders.Add(-1) return nil }) if err != nil { @@ -2212,7 +2212,7 @@ func testConcurrentClose(tc *testContext) bool { // active readers open. time.AfterFunc(time.Millisecond*250, func() { close(finishReaders) }) <-dbClosed - if nr := atomic.LoadInt32(&activeReaders); nr != 0 { + if nr := activeReaders.Load(); nr != 0 { tc.t.Errorf("Close did not appear to block with active "+ "readers: %d active", nr) return false diff --git a/database/go.mod b/database/go.mod index 4abfe3257..730dfdecb 100644 --- a/database/go.mod +++ b/database/go.mod @@ -1,6 +1,6 @@ module github.com/decred/dcrd/database/v3 -go 1.18 +go 1.19 require ( github.com/decred/dcrd/chaincfg/chainhash v1.0.5 diff --git a/peer/go.mod b/peer/go.mod index 918a18dac..d90e37d28 100644 --- a/peer/go.mod +++ b/peer/go.mod @@ -1,6 +1,6 @@ module github.com/decred/dcrd/peer/v4 -go 1.18 +go 1.19 require ( github.com/davecgh/go-spew v1.1.1 diff --git a/peer/peer.go b/peer/peer.go index 75ec208b7..dcd49c9c5 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -80,7 +80,7 @@ const ( var ( // nodeCount is the total number of peer connections made since startup // and is used to assign an id to a peer. - nodeCount int32 + nodeCount atomic.Int32 // sentNonces houses the unique nonces that are generated when pushing // version messages that are used to detect self connections. @@ -451,12 +451,11 @@ type HostToNetAddrFunc func(host string, port uint16, // of specific types that typically require common special handling are // provided as a convenience. type Peer struct { - // The following variables must only be used atomically. - bytesReceived uint64 - bytesSent uint64 - lastRecv int64 - lastSend int64 - disconnect int32 + bytesReceived atomic.Uint64 + bytesSent atomic.Uint64 + lastRecv atomic.Int64 + lastSend atomic.Int64 + disconnect atomic.Bool conn net.Conn connMtx sync.Mutex @@ -735,14 +734,14 @@ func (p *Peer) LastBlock() int64 { // // This function is safe for concurrent access. func (p *Peer) LastSend() time.Time { - return time.Unix(atomic.LoadInt64(&p.lastSend), 0) + return time.Unix(p.lastSend.Load(), 0) } // LastRecv returns the last recv time of the peer. // // This function is safe for concurrent access. func (p *Peer) LastRecv() time.Time { - return time.Unix(atomic.LoadInt64(&p.lastRecv), 0) + return time.Unix(p.lastRecv.Load(), 0) } // LocalAddr returns the local address of the connection or nil if the peer is @@ -761,14 +760,14 @@ func (p *Peer) LocalAddr() net.Addr { // // This function is safe for concurrent access. func (p *Peer) BytesSent() uint64 { - return atomic.LoadUint64(&p.bytesSent) + return p.bytesSent.Load() } // BytesReceived returns the total number of bytes received by the peer. // // This function is safe for concurrent access. func (p *Peer) BytesReceived() uint64 { - return atomic.LoadUint64(&p.bytesReceived) + return p.bytesReceived.Load() } // TimeConnected returns the time at which the peer connected. @@ -1015,7 +1014,7 @@ func (p *Peer) readMessage() (wire.Message, []byte, error) { } n, msg, buf, err := wire.ReadMessageN(p.conn, p.ProtocolVersion(), p.cfg.Net) - atomic.AddUint64(&p.bytesReceived, uint64(n)) + p.bytesReceived.Add(uint64(n)) // Calculate and store the message hash of any mixing message // immediately after deserializing it. @@ -1052,7 +1051,7 @@ func (p *Peer) readMessage() (wire.Message, []byte, error) { // writeMessage sends a wire message to the peer with logging. func (p *Peer) writeMessage(msg wire.Message) error { // Don't do anything if we're disconnecting. - if atomic.LoadInt32(&p.disconnect) != 0 { + if p.disconnect.Load() { return nil } @@ -1077,7 +1076,7 @@ func (p *Peer) writeMessage(msg wire.Message) error { // Write the message to the peer. n, err := wire.WriteMessageN(p.conn, msg, p.ProtocolVersion(), p.cfg.Net) - atomic.AddUint64(&p.bytesSent, uint64(n)) + p.bytesSent.Add(uint64(n)) if p.cfg.Listeners.OnWrite != nil { p.cfg.Listeners.OnWrite(p, n, msg, err) } @@ -1090,7 +1089,7 @@ func (p *Peer) writeMessage(msg wire.Message) error { func (p *Peer) shouldHandleReadError(err error) bool { // No logging or reject message when the peer is being forcibly // disconnected. - if atomic.LoadInt32(&p.disconnect) != 0 { + if p.disconnect.Load() { return false } @@ -1350,7 +1349,7 @@ cleanup: // goroutine. func (p *Peer) inHandler() { out: - for atomic.LoadInt32(&p.disconnect) == 0 { + for !p.disconnect.Load() { // Read a message and stop the idle timer as soon as the read // is done. The timer is reset below for the next iteration if // needed. @@ -1370,7 +1369,7 @@ out: break out } - atomic.StoreInt64(&p.lastRecv, time.Now().Unix()) + p.lastRecv.Store(time.Now().Unix()) select { case p.stallControl <- stallControlMsg{sccReceiveMessage, rmsg}: case <-p.quit: @@ -1688,7 +1687,7 @@ out: // is no queued inventory. // version is known if send queue has any entries. switch { - case atomic.LoadInt32(&p.disconnect) != 0: + case p.disconnect.Load(): continue case len(invSendQueue) == 0: trickleTimer.Reset(trickleTimeout()) @@ -1761,7 +1760,7 @@ cleanup: // should be logged. func (p *Peer) shouldLogWriteError(err error) bool { // No logging when the peer is being forcibly disconnected. - if atomic.LoadInt32(&p.disconnect) != 0 { + if p.disconnect.Load() { return false } @@ -1820,7 +1819,7 @@ out: // message that it has been sent (if requested), and // signal the send queue to the deliver the next queued // message. - atomic.StoreInt64(&p.lastSend, time.Now().Unix()) + p.lastSend.Store(time.Now().Unix()) if msg.doneChan != nil { msg.doneChan <- struct{}{} } @@ -1948,7 +1947,7 @@ func (p *Peer) Connected() bool { p.connMtx.Lock() defer p.connMtx.Unlock() - return p.conn != nil && atomic.LoadInt32(&p.disconnect) == 0 + return p.conn != nil && !p.disconnect.Load() } // Disconnect disconnects the peer by closing the connection. Calling this @@ -1963,7 +1962,7 @@ func (p *Peer) Disconnect() { p.conn.Close() } - if atomic.CompareAndSwapInt32(&p.disconnect, 0, 1) { + if p.disconnect.CompareAndSwap(false, true) { close(p.quit) } } @@ -2011,7 +2010,7 @@ func (p *Peer) readRemoteVersionMsg() error { // Set the peer's ID and user agent. p.flagsMtx.Lock() - p.id = atomic.AddInt32(&nodeCount, 1) + p.id = nodeCount.Add(1) p.userAgent = msg.UserAgent p.flagsMtx.Unlock() diff --git a/rpcclient/go.mod b/rpcclient/go.mod index 88abf586f..146ebbf2b 100644 --- a/rpcclient/go.mod +++ b/rpcclient/go.mod @@ -1,6 +1,6 @@ module github.com/decred/dcrd/rpcclient/v8 -go 1.18 +go 1.19 require ( github.com/decred/dcrd/chaincfg/chainhash v1.0.5 diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index bc8d5e2dc..2ab608887 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -1,5 +1,5 @@ // Copyright (c) 2014-2016 The btcsuite developers -// Copyright (c) 2015-2025 The Decred developers +// Copyright (c) 2015-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -143,7 +143,7 @@ type jsonRequest struct { // the returned future will block until the result is available if it's not // already. type Client struct { - id uint64 // atomic, so must stay 64-bit aligned + id atomic.Uint64 // config holds the connection configuration associated with this // client. @@ -212,7 +212,7 @@ func (c *Client) String() string { // this function should be used to ensure the ID is unique amongst all requests // being made. func (c *Client) NextID() uint64 { - return atomic.AddUint64(&c.id, 1) + return c.id.Add(1) } // addRequest associates the passed jsonRequest with its id. This allows the