@@ -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
9397func (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
129139func (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