Skip to content

Commit

Permalink
docs: clarify the semantics of concurrent Read calls (#136)
Browse files Browse the repository at this point in the history
Concurrent operations on the stream are "safe" inasmuch as they don't cause a
data race. That is, calling close concurrently with a read won't panic, you can
write and read concurrently, and reading from two different goroutines shouldn't
result in short reads. But there's no intended guarantee that the reads are
semantically meaningful if you're reading concurrently.

Fixes: #128
  • Loading branch information
tgross authored Oct 2, 2024
1 parent 17017e9 commit 49eecf3
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ func (s *Stream) StreamID() uint32 {
return s.id
}

// Read is used to read from the stream
// Read is used to read from the stream. It is safe to call Write, Read, and/or
// Close concurrently but Stream provides no guarantees that concurrent Reads
// will receive data in response to Writes made from the same goroutine.
func (s *Stream) Read(b []byte) (n int, err error) {
defer asyncNotify(s.recvNotifyCh)
START:
Expand Down Expand Up @@ -158,7 +160,9 @@ WAIT:
goto START
}

// Write is used to write to the stream
// Write is used to write to the stream. It is safe to call Write, Read, and/or
// Close concurrently but Stream provides no guarantees that concurrent Reads
// will receive data in response to Writes made from the same goroutine.
func (s *Stream) Write(b []byte) (n int, err error) {
s.sendLock.Lock()
defer s.sendLock.Unlock()
Expand Down Expand Up @@ -320,7 +324,8 @@ func (s *Stream) sendClose() error {
return nil
}

// Close is used to close the stream
// Close is used to close the stream. It is safe to call Write, Read, and/or
// Close concurrently.
func (s *Stream) Close() error {
closeStream := false
s.stateLock.Lock()
Expand Down

0 comments on commit 49eecf3

Please sign in to comment.