From 8bcb6337d193dffc69952567e1ceb1a6fe6100d4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 25 Apr 2022 11:58:24 +0100 Subject: [PATCH] protect against concurrent use of Stream.Write (#3381) --- send_stream.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/send_stream.go b/send_stream.go index 946243ca12f..b23df00b377 100644 --- a/send_stream.go +++ b/send_stream.go @@ -50,6 +50,7 @@ type sendStream struct { nextFrame *wire.StreamFrame writeChan chan struct{} + writeOnce chan struct{} deadline time.Time flowController flowcontrol.StreamFlowController @@ -73,6 +74,7 @@ func newSendStream( sender: sender, flowController: flowController, writeChan: make(chan struct{}, 1), + writeOnce: make(chan struct{}, 1), // cap: 1, to protect against concurrent use of Write version: version, } s.ctx, s.ctxCancel = context.WithCancel(context.Background()) @@ -84,6 +86,12 @@ func (s *sendStream) StreamID() protocol.StreamID { } func (s *sendStream) Write(p []byte) (int, error) { + // Concurrent use of Write is not permitted (and doesn't make any sense), + // but sometimes people do it anyway. + // Make sure that we only execute one call at any given time to avoid hard to debug failures. + s.writeOnce <- struct{}{} + defer func() { <-s.writeOnce }() + s.mutex.Lock() defer s.mutex.Unlock()