@@ -19,6 +19,7 @@ import (
19
19
"fmt"
20
20
"net"
21
21
"reflect"
22
+ "sync"
22
23
"time"
23
24
24
25
"github.com/blinklabs-io/gouroboros/cbor"
@@ -42,6 +43,8 @@ type Connection struct {
42
43
conversation []ConversationEntry
43
44
muxer * muxer.Muxer
44
45
muxerRecvChan chan * muxer.Segment
46
+ doneChan chan any
47
+ onceClose sync.Once
45
48
}
46
49
47
50
// NewConnection returns a new Connection with the provided conversation entries
@@ -51,6 +54,7 @@ func NewConnection(
51
54
) net.Conn {
52
55
c := & Connection {
53
56
conversation : conversation ,
57
+ doneChan : make (chan any ),
54
58
}
55
59
c .conn , c .mockConn = net .Pipe ()
56
60
// Start a muxer on the mocked side of the connection
@@ -91,14 +95,20 @@ func (c *Connection) Write(b []byte) (n int, err error) {
91
95
92
96
// Close closes both sides of the connection. This is needed to satisfy the net.Conn interface
93
97
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
102
112
}
103
113
104
114
// 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 {
128
138
129
139
func (c * Connection ) asyncLoop () {
130
140
for _ , entry := range c .conversation {
141
+ select {
142
+ case <- c .doneChan :
143
+ return
144
+ default :
145
+ }
131
146
switch entry .Type {
132
147
case EntryTypeInput :
133
148
if err := c .processInputEntry (entry ); err != nil {
0 commit comments