From 6f31b3ae404a7cd47885af0a1cc77fa7ae34e4c0 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 17 Apr 2024 12:54:49 +0200 Subject: [PATCH] server: fix failingListener data race in tests WARNING: DATA RACE Read at 0x00c00002b788 by goroutine 44: github.com/emersion/go-smtp_test.(*failingListener).Close() /home/simon/src/go-smtp/server_test.go:193 +0x34 github.com/emersion/go-smtp.(*Server).Close() /home/simon/src/go-smtp/server.go:251 +0x181 github.com/emersion/go-smtp_test.TestServerAcceptErrorHandling() /home/simon/src/go-smtp/server_test.go:323 +0x771 testing.tRunner() /usr/lib/go/src/testing/testing.go:1689 +0x21e testing.(*T).Run.gowrap1() /usr/lib/go/src/testing/testing.go:1742 +0x44 Previous write at 0x00c00002b788 by goroutine 45: github.com/emersion/go-smtp_test.(*failingListener).Close() /home/simon/src/go-smtp/server_test.go:195 +0xdb github.com/emersion/go-smtp_test.TestServerAcceptErrorHandling.func1() /home/simon/src/go-smtp/server_test.go:316 +0xab Goroutine 44 (running) created at: testing.(*T).Run() /usr/lib/go/src/testing/testing.go:1742 +0x825 testing.runTests.func1() /usr/lib/go/src/testing/testing.go:2161 +0x85 testing.tRunner() /usr/lib/go/src/testing/testing.go:1689 +0x21e testing.runTests() /usr/lib/go/src/testing/testing.go:2159 +0x8be testing.(*M).Run() /usr/lib/go/src/testing/testing.go:2027 +0xf17 main.main() _testmain.go:163 +0x2bd Goroutine 45 (finished) created at: github.com/emersion/go-smtp_test.TestServerAcceptErrorHandling() /home/simon/src/go-smtp/server_test.go:314 +0x5d5 testing.tRunner() /usr/lib/go/src/testing/testing.go:1689 +0x21e testing.(*T).Run.gowrap1() /usr/lib/go/src/testing/testing.go:1742 +0x44 --- server_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server_test.go b/server_test.go index b0bf4c0..add9390 100644 --- a/server_test.go +++ b/server_test.go @@ -10,6 +10,7 @@ import ( "log" "net" "strings" + "sync" "testing" "github.com/emersion/go-sasl" @@ -173,6 +174,7 @@ func (s *session) LMTPData(r io.Reader, collector smtp.StatusCollector) error { type failingListener struct { c chan error closed bool + mu sync.Mutex } func newFailingListener() *failingListener { @@ -180,6 +182,9 @@ func newFailingListener() *failingListener { } func (l *failingListener) Send(err error) { + l.mu.Lock() + defer l.mu.Unlock() + if !l.closed { l.c <- err } @@ -190,6 +195,9 @@ func (l *failingListener) Accept() (net.Conn, error) { } func (l *failingListener) Close() error { + l.mu.Lock() + defer l.mu.Unlock() + if !l.closed { close(l.c) l.closed = true