55 "context"
66 "errors"
77 "io"
8+ "log"
89 "os"
910
1011 foxyevent "github.com/strowk/foxy-contexts/pkg/foxy_event"
@@ -92,6 +93,7 @@ func (s *stdioTransport) run(
9293 }
9394 }
9495 }
96+ log .Printf ("stopped reading responses" )
9597 close (s .stoppedReadingResponses )
9698 }()
9799
@@ -115,22 +117,45 @@ func (s *stdioTransport) run(
115117 close (s .stoppedReadingInput )
116118 }()
117119
118- <- s .shuttingDown
120+ // wait for either shutting down or stopped reading input
121+ select {
122+ case <- s .shuttingDown :
123+ // if we got shutting down signal,
124+ // we need to wait until we stop reading input,
125+ // which waits for shutdown by itself
126+ <- s .stoppedReadingInput
127+ case <- s .stoppedReadingInput :
128+ // if we stopped reading input, we can now initiate shutdown
129+ close (s .shuttingDown )
130+ }
131+
132+ // wait until we stop reading responses,
133+ // before signaling that we are stopped
119134 <- s .stoppedReadingResponses
120- <- s .stoppedReadingInput
121135
122136 close (s .stopped )
123-
124137 return nil
125138}
126139
127140func (s * stdioTransport ) Shutdown (ctx context.Context ) error {
128- close (s .shuttingDown )
141+ safeClose (s .shuttingDown )
129142
143+ // this waits either till we are stopped or we cannot wait anymore
130144 select {
131145 case <- s .stopped :
132146 return nil
133147 case <- ctx .Done ():
134148 return ctx .Err ()
135149 }
136150}
151+
152+ func safeClose (ch chan struct {}) {
153+ defer func () {
154+ if r := recover (); r != nil {
155+ // it is possible to panic if channel is already closed
156+ // in which case we just go on, as it is possible that
157+ // Shutdown would be called soon after transport is stopped
158+ }
159+ }()
160+ close (ch )
161+ }
0 commit comments