diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2014-04-25 06:44:51 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2014-04-25 06:44:51 -0700 |
| commit | 13ea1fd233465bc5dd410c8c64c8120ab249ab69 (patch) | |
| tree | d1461cc38f872f439d2c2e65c51a4b44e994f82f /src/pkg/strings | |
| parent | f40e574d85cd9bc492f62e7cbee8924a8a5e584e (diff) | |
| download | go-13ea1fd233465bc5dd410c8c64c8120ab249ab69.tar.xz | |
net/http, strings, bytes: fix http race, revert part of Reader behavior change
I fixed this data race regression in two ways: in net/http itself, and also
partially reverting the change from https://golang.org/cl/77580046 .
Previously a Read from a strings.Reader or bytes.Reader returning 0 bytes
would not be a memory write. After 77580046 it was. This reverts that back
in case others depended on that. Also adds tests.
Fixes #7856
LGTM=ruiu, iant
R=iant, ruiu
CC=golang-codereviews, gri
https://golang.org/cl/94740044
Diffstat (limited to 'src/pkg/strings')
| -rw-r--r-- | src/pkg/strings/reader.go | 2 | ||||
| -rw-r--r-- | src/pkg/strings/reader_test.go | 21 | ||||
| -rw-r--r-- | src/pkg/strings/strings_test.go | 2 |
3 files changed, 23 insertions, 2 deletions
diff --git a/src/pkg/strings/reader.go b/src/pkg/strings/reader.go index ee83ceb505..82df974398 100644 --- a/src/pkg/strings/reader.go +++ b/src/pkg/strings/reader.go @@ -29,13 +29,13 @@ func (r *Reader) Len() int { } func (r *Reader) Read(b []byte) (n int, err error) { - r.prevRune = -1 if len(b) == 0 { return 0, nil } if r.i >= int64(len(r.s)) { return 0, io.EOF } + r.prevRune = -1 n = copy(b, r.s[r.i:]) r.i += int64(n) return diff --git a/src/pkg/strings/reader_test.go b/src/pkg/strings/reader_test.go index 4d95355af7..bee90eb258 100644 --- a/src/pkg/strings/reader_test.go +++ b/src/pkg/strings/reader_test.go @@ -115,6 +115,27 @@ func TestReaderAtConcurrent(t *testing.T) { wg.Wait() } +func TestEmptyReaderConcurrent(t *testing.T) { + // Test for the race detector, to verify a Read that doesn't yield any bytes + // is okay to use from multiple goroutines. This was our historic behavior. + // See golang.org/issue/7856 + r := strings.NewReader("") + var wg sync.WaitGroup + for i := 0; i < 5; i++ { + wg.Add(2) + go func() { + defer wg.Done() + var buf [1]byte + r.Read(buf[:]) + }() + go func() { + defer wg.Done() + r.Read(nil) + }() + } + wg.Wait() +} + func TestWriteTo(t *testing.T) { const str = "0123456789" for i := 0; i <= len(str); i++ { diff --git a/src/pkg/strings/strings_test.go b/src/pkg/strings/strings_test.go index 95a42019a3..e40a18015e 100644 --- a/src/pkg/strings/strings_test.go +++ b/src/pkg/strings/strings_test.go @@ -862,7 +862,7 @@ var UnreadRuneErrorTests = []struct { name string f func(*Reader) }{ - {"Read", func(r *Reader) { r.Read([]byte{}) }}, + {"Read", func(r *Reader) { r.Read([]byte{0}) }}, {"ReadByte", func(r *Reader) { r.ReadByte() }}, {"UnreadRune", func(r *Reader) { r.UnreadRune() }}, {"Seek", func(r *Reader) { r.Seek(0, 1) }}, |
