@@ -181,6 +181,10 @@ type Server struct {
181181type serverInternalState struct {
182182 mu sync.Mutex
183183 activeConns map [* serverConn ]struct {}
184+
185+ // Pool of error channels. This is per-Server rather than global
186+ // because channels can't be reused across synctest bubbles.
187+ errChanPool sync.Pool
184188}
185189
186190func (s * serverInternalState ) registerConn (sc * serverConn ) {
@@ -212,6 +216,27 @@ func (s *serverInternalState) startGracefulShutdown() {
212216 s .mu .Unlock ()
213217}
214218
219+ // Global error channel pool used for uninitialized Servers.
220+ // We use a per-Server pool when possible to avoid using channels across synctest bubbles.
221+ var errChanPool = sync.Pool {
222+ New : func () any { return make (chan error , 1 ) },
223+ }
224+
225+ func (s * serverInternalState ) getErrChan () chan error {
226+ if s == nil {
227+ return errChanPool .Get ().(chan error ) // Server used without calling ConfigureServer
228+ }
229+ return s .errChanPool .Get ().(chan error )
230+ }
231+
232+ func (s * serverInternalState ) putErrChan (ch chan error ) {
233+ if s == nil {
234+ errChanPool .Put (ch ) // Server used without calling ConfigureServer
235+ return
236+ }
237+ s .errChanPool .Put (ch )
238+ }
239+
215240// ConfigureServer adds HTTP/2 support to a net/http Server.
216241//
217242// The configuration conf may be nil.
@@ -224,7 +249,10 @@ func ConfigureServer(s *http.Server, conf *Server) error {
224249 if conf == nil {
225250 conf = new (Server )
226251 }
227- conf .state = & serverInternalState {activeConns : make (map [* serverConn ]struct {})}
252+ conf .state = & serverInternalState {
253+ activeConns : make (map [* serverConn ]struct {}),
254+ errChanPool : sync.Pool {New : func () any { return make (chan error , 1 ) }},
255+ }
228256 if h1 , h2 := s , conf ; h2 .IdleTimeout == 0 {
229257 if h1 .IdleTimeout != 0 {
230258 h2 .IdleTimeout = h1 .IdleTimeout
@@ -1124,33 +1152,14 @@ func (sc *serverConn) readPreface() error {
11241152 }
11251153}
11261154
1127- var errChanPool = sync.Pool {
1128- New : func () interface {} { return make (chan error , 1 ) },
1129- }
1130-
1131- func getErrChan () chan error {
1132- if inTests {
1133- // Channels cannot be reused across synctest tests.
1134- return make (chan error , 1 )
1135- } else {
1136- return errChanPool .Get ().(chan error )
1137- }
1138- }
1139-
1140- func putErrChan (ch chan error ) {
1141- if ! inTests {
1142- errChanPool .Put (ch )
1143- }
1144- }
1145-
11461155var writeDataPool = sync.Pool {
11471156 New : func () interface {} { return new (writeData ) },
11481157}
11491158
11501159// writeDataFromHandler writes DATA response frames from a handler on
11511160// the given stream.
11521161func (sc * serverConn ) writeDataFromHandler (stream * stream , data []byte , endStream bool ) error {
1153- ch := getErrChan ()
1162+ ch := sc . srv . state . getErrChan ()
11541163 writeArg := writeDataPool .Get ().(* writeData )
11551164 * writeArg = writeData {stream .id , data , endStream }
11561165 err := sc .writeFrameFromHandler (FrameWriteRequest {
@@ -1182,7 +1191,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea
11821191 return errStreamClosed
11831192 }
11841193 }
1185- putErrChan (ch )
1194+ sc . srv . state . putErrChan (ch )
11861195 if frameWriteDone {
11871196 writeDataPool .Put (writeArg )
11881197 }
@@ -2436,7 +2445,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro
24362445 // waiting for this frame to be written, so an http.Flush mid-handler
24372446 // writes out the correct value of keys, before a handler later potentially
24382447 // mutates it.
2439- errc = getErrChan ()
2448+ errc = sc . srv . state . getErrChan ()
24402449 }
24412450 if err := sc .writeFrameFromHandler (FrameWriteRequest {
24422451 write : headerData ,
@@ -2448,7 +2457,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro
24482457 if errc != nil {
24492458 select {
24502459 case err := <- errc :
2451- putErrChan (errc )
2460+ sc . srv . state . putErrChan (errc )
24522461 return err
24532462 case <- sc .doneServing :
24542463 return errClientDisconnected
@@ -3129,7 +3138,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
31293138 method : opts .Method ,
31303139 url : u ,
31313140 header : cloneHeader (opts .Header ),
3132- done : getErrChan (),
3141+ done : sc . srv . state . getErrChan (),
31333142 }
31343143
31353144 select {
@@ -3146,7 +3155,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
31463155 case <- st .cw :
31473156 return errStreamClosed
31483157 case err := <- msg .done :
3149- putErrChan (msg .done )
3158+ sc . srv . state . putErrChan (msg .done )
31503159 return err
31513160 }
31523161}
0 commit comments