Skip to content

Commit 28b7880

Browse files
authored
server: refactor to use atomic type (#2058)
1 parent 68d21ed commit 28b7880

File tree

2 files changed

+27
-28
lines changed

2 files changed

+27
-28
lines changed

server.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ type Server struct {
315315

316316
mu sync.Mutex
317317

318-
concurrency uint32
319-
open int32
320-
stop int32
318+
concurrency atomic.Uint32
319+
open atomic.Int32
320+
stop atomic.Int32
321321

322-
rejectedRequestsCount uint32
322+
rejectedRequestsCount atomic.Uint32
323323

324324
// Whether to disable keep-alive connections.
325325
//
@@ -1871,8 +1871,8 @@ func (s *Server) Serve(ln net.Listener) error {
18711871
// This way we can't get into any weird state where just after accepting
18721872
// a connection Shutdown is called which reads open as 0 because it isn't
18731873
// incremented yet.
1874-
atomic.AddInt32(&s.open, 1)
1875-
defer atomic.AddInt32(&s.open, -1)
1874+
s.open.Add(1)
1875+
defer s.open.Add(-1)
18761876

18771877
for {
18781878
c, err := acceptConn(s, ln, &lastPerIPErrorTime)
@@ -1884,10 +1884,10 @@ func (s *Server) Serve(ln net.Listener) error {
18841884
return err
18851885
}
18861886
s.setState(c, StateNew)
1887-
atomic.AddInt32(&s.open, 1)
1887+
s.open.Add(1)
18881888
if !wp.Serve(c) {
1889-
atomic.AddInt32(&s.open, -1)
1890-
atomic.AddUint32(&s.rejectedRequestsCount, 1)
1889+
s.open.Add(-1)
1890+
s.rejectedRequestsCount.Add(1)
18911891
s.writeFastError(c, StatusServiceUnavailable,
18921892
"The connection cannot be served because Server.Concurrency limit exceeded")
18931893
c.Close()
@@ -1940,8 +1940,8 @@ func (s *Server) ShutdownWithContext(ctx context.Context) (err error) {
19401940
s.mu.Lock()
19411941
defer s.mu.Unlock()
19421942

1943-
atomic.StoreInt32(&s.stop, 1)
1944-
defer atomic.StoreInt32(&s.stop, 0)
1943+
s.stop.Store(1)
1944+
defer s.stop.Store(0)
19451945

19461946
if s.ln == nil {
19471947
return nil
@@ -1962,7 +1962,7 @@ func (s *Server) ShutdownWithContext(ctx context.Context) (err error) {
19621962
for {
19631963
s.closeIdleConns()
19641964

1965-
if open := atomic.LoadInt32(&s.open); open == 0 {
1965+
if open := s.open.Load(); open == 0 {
19661966
// There may be a pending request to call ctx.Done(). Therefore, we only set it to nil when open == 0.
19671967
s.done = nil
19681968
return lnerr
@@ -2082,19 +2082,19 @@ func (s *Server) ServeConn(c net.Conn) error {
20822082
c = pic
20832083
}
20842084

2085-
n := int(atomic.AddUint32(&s.concurrency, 1)) // #nosec G115
2085+
n := int(s.concurrency.Add(1)) // #nosec G115
20862086
if n > s.getConcurrency() {
2087-
atomic.AddUint32(&s.concurrency, ^uint32(0))
2087+
s.concurrency.Add(^uint32(0))
20882088
s.writeFastError(c, StatusServiceUnavailable, "The connection cannot be served because Server.Concurrency limit exceeded")
20892089
c.Close()
20902090
return ErrConcurrencyLimit
20912091
}
20922092

2093-
atomic.AddInt32(&s.open, 1)
2093+
s.open.Add(1)
20942094

20952095
err := s.serveConn(c)
20962096

2097-
atomic.AddUint32(&s.concurrency, ^uint32(0))
2097+
s.concurrency.Add(^uint32(0))
20982098

20992099
if err != errHijacked {
21002100
errc := c.Close()
@@ -2116,29 +2116,29 @@ var errHijacked = errors.New("connection has been hijacked")
21162116
//
21172117
// This function is intended be used by monitoring systems.
21182118
func (s *Server) GetCurrentConcurrency() uint32 {
2119-
return atomic.LoadUint32(&s.concurrency)
2119+
return s.concurrency.Load()
21202120
}
21212121

21222122
// GetOpenConnectionsCount returns a number of opened connections.
21232123
//
21242124
// This function is intended be used by monitoring systems.
21252125
func (s *Server) GetOpenConnectionsCount() int32 {
2126-
if atomic.LoadInt32(&s.stop) == 0 {
2126+
if s.stop.Load() == 0 {
21272127
// Decrement by one to avoid reporting the extra open value that gets
21282128
// counted while the server is listening.
2129-
return atomic.LoadInt32(&s.open) - 1
2129+
return s.open.Load() - 1
21302130
}
21312131
// This is not perfect, because s.stop could have changed to zero
21322132
// before we load the value of s.open. However, in the common case
21332133
// this avoids underreporting open connections by 1 during server shutdown.
2134-
return atomic.LoadInt32(&s.open)
2134+
return s.open.Load()
21352135
}
21362136

21372137
// GetRejectedConnectionsCount returns a number of rejected connections.
21382138
//
21392139
// This function is intended be used by monitoring systems.
21402140
func (s *Server) GetRejectedConnectionsCount() uint32 {
2141-
return atomic.LoadUint32(&s.rejectedRequestsCount)
2141+
return s.rejectedRequestsCount.Load()
21422142
}
21432143

21442144
func (s *Server) getConcurrency() int {
@@ -2169,13 +2169,13 @@ func (s *Server) idleTimeout() time.Duration {
21692169
}
21702170

21712171
func (s *Server) serveConnCleanup() {
2172-
atomic.AddInt32(&s.open, -1)
2173-
atomic.AddUint32(&s.concurrency, ^uint32(0))
2172+
s.open.Add(-1)
2173+
s.concurrency.Add(^uint32(0))
21742174
}
21752175

21762176
func (s *Server) serveConn(c net.Conn) (err error) {
21772177
defer s.serveConnCleanup()
2178-
atomic.AddUint32(&s.concurrency, 1)
2178+
s.concurrency.Add(1)
21792179

21802180
var proto string
21812181
if proto, err = s.getNextProto(c); err != nil {
@@ -2487,7 +2487,7 @@ func (s *Server) serveConn(c net.Conn) (err error) {
24872487
connectionClose = connectionClose ||
24882488
(s.MaxRequestsPerConn > 0 && connRequestNum >= uint64(s.MaxRequestsPerConn)) || // #nosec G115
24892489
ctx.Response.Header.ConnectionClose() ||
2490-
(s.CloseOnShutdown && atomic.LoadInt32(&s.stop) == 1)
2490+
(s.CloseOnShutdown && s.stop.Load() == 1)
24912491
if connectionClose {
24922492
ctx.Response.Header.SetConnectionClose()
24932493
} else if !ctx.Request.Header.IsHTTP11() {
@@ -2563,7 +2563,7 @@ func (s *Server) serveConn(c net.Conn) (err error) {
25632563
ctx.Request.Reset()
25642564
ctx.Response.Reset()
25652565

2566-
if atomic.LoadInt32(&s.stop) == 1 {
2566+
if s.stop.Load() == 1 {
25672567
err = nil
25682568
break
25692569
}

server_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"runtime"
1717
"strings"
1818
"sync"
19-
"sync/atomic"
2019
"testing"
2120
"time"
2221

@@ -3934,7 +3933,7 @@ func TestShutdownWithContext(t *testing.T) {
39343933
t.Fatalf("unexpected err %v. Expecting %v", err, context.DeadlineExceeded)
39353934
}
39363935
}
3937-
if o := atomic.LoadInt32(&s.open); o != 1 {
3936+
if o := s.open.Load(); o != 1 {
39383937
t.Fatalf("unexpected open connection num: %#v. Expecting %#v", o, 1)
39393938
}
39403939
}

0 commit comments

Comments
 (0)