Skip to content

Commit 3a50e03

Browse files
authored
fix: exit goroutine on close in ouroboros_mock (#534)
Fixes #533
1 parent 7fbcb28 commit 3a50e03

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

internal/test/ouroboros_mock/connection.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"fmt"
2020
"net"
2121
"reflect"
22+
"sync"
2223
"time"
2324

2425
"github.com/blinklabs-io/gouroboros/cbor"
@@ -42,6 +43,8 @@ type Connection struct {
4243
conversation []ConversationEntry
4344
muxer *muxer.Muxer
4445
muxerRecvChan chan *muxer.Segment
46+
doneChan chan any
47+
onceClose sync.Once
4548
}
4649

4750
// NewConnection returns a new Connection with the provided conversation entries
@@ -51,6 +54,7 @@ func NewConnection(
5154
) net.Conn {
5255
c := &Connection{
5356
conversation: conversation,
57+
doneChan: make(chan any),
5458
}
5559
c.conn, c.mockConn = net.Pipe()
5660
// Start a muxer on the mocked side of the connection
@@ -91,14 +95,20 @@ func (c *Connection) Write(b []byte) (n int, err error) {
9195

9296
// Close closes both sides of the connection. This is needed to satisfy the net.Conn interface
9397
func (c *Connection) Close() error {
94-
c.muxer.Stop()
95-
if err := c.conn.Close(); err != nil {
96-
return err
97-
}
98-
if err := c.mockConn.Close(); err != nil {
99-
return err
100-
}
101-
return nil
98+
var retErr error
99+
c.onceClose.Do(func() {
100+
close(c.doneChan)
101+
c.muxer.Stop()
102+
if err := c.conn.Close(); err != nil {
103+
retErr = err
104+
return
105+
}
106+
if err := c.mockConn.Close(); err != nil {
107+
retErr = err
108+
return
109+
}
110+
})
111+
return retErr
102112
}
103113

104114
// LocalAddr provides a proxy to the client-side connection's LocalAddr function. This is needed to satisfy the net.Conn interface
@@ -128,6 +138,11 @@ func (c *Connection) SetWriteDeadline(t time.Time) error {
128138

129139
func (c *Connection) asyncLoop() {
130140
for _, entry := range c.conversation {
141+
select {
142+
case <-c.doneChan:
143+
return
144+
default:
145+
}
131146
switch entry.Type {
132147
case EntryTypeInput:
133148
if err := c.processInputEntry(entry); err != nil {

0 commit comments

Comments
 (0)