Skip to content

Commit

Permalink
fix: dial timeout panic
Browse files Browse the repository at this point in the history
  • Loading branch information
joway committed Oct 13, 2023
1 parent cf96b81 commit aaa2a0f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
37 changes: 37 additions & 0 deletions connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"net"
"os"
"runtime"
"strings"
"sync"
"sync/atomic"
"syscall"
Expand Down Expand Up @@ -638,3 +639,39 @@ func TestConnectionServerClose(t *testing.T) {
//time.Sleep(time.Second)
wg.Wait()
}

func TestConnectionDailTimeoutAndClose(t *testing.T) {
ln, err := createTestListener("tcp", ":12345")
MustNil(t, err)
defer ln.Close()

el, err := NewEventLoop(
func(ctx context.Context, connection Connection) error {
_, err = connection.Reader().Next(connection.Reader().Len())
return err
},
)
defer el.Shutdown(context.Background())
go func() {
err := el.Serve(ln)
if err != nil {
t.Logf("servce end with error: %v", err)
}
}()

loops := 100
conns := 100
for l := 0; l < loops; l++ {
var wg sync.WaitGroup
wg.Add(conns)
for i := 0; i < conns; i++ {
go func() {
defer wg.Done()
conn, err := DialConnection("tcp", ":12345", time.Nanosecond)
Assert(t, strings.Contains(err.Error(), "i/o timeout") || err == nil)
_ = conn
}()
}
wg.Wait()
}
}
9 changes: 6 additions & 3 deletions net_polldesc.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ func (pd *pollDesc) WaitWrite(ctx context.Context) (err error) {
}

select {
case <-pd.closeTrigger:
case <-pd.closeTrigger: // triggered by poller
// no need to detach, since poller has done it in OnHup.
return Exception(ErrConnClosed, "by peer")
case <-pd.writeTrigger:
case <-pd.writeTrigger: // triggered by poller
err = nil
case <-ctx.Done():
case <-ctx.Done(): // triggered by ctx
// deregister from poller, upper caller function will close fd
// detach first but there's a very small possibility that operator is doing in poller,
// so need call unused() to wait operator done
pd.detach()
pd.operator.unused()
err = mapErr(ctx.Err())
}
// double check close trigger
Expand Down

0 comments on commit aaa2a0f

Please sign in to comment.