Skip to content

Commit

Permalink
http: fix BodyReader multi close bug
Browse files Browse the repository at this point in the history
  • Loading branch information
lesismal committed Oct 25, 2024
1 parent 3a34aa0 commit fd8d727
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 18 deletions.
22 changes: 6 additions & 16 deletions mempool/mempool.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ type MemPool struct {
}

// New .
//
//go:norace
func New(bufSize, freeSize int) Allocator {
if bufSize <= 0 {
bufSize = 64
Expand All @@ -45,8 +43,6 @@ func New(bufSize, freeSize int) Allocator {
}

// Malloc .
//
//go:norace
func (mp *MemPool) Malloc(size int) []byte {
var ret []byte
if size > mp.freeSize {
Expand All @@ -65,8 +61,6 @@ func (mp *MemPool) Malloc(size int) []byte {
}

// Realloc .
//
//go:norace
func (mp *MemPool) Realloc(buf []byte, size int) []byte {
if size <= cap(buf) {
return buf[:size]
Expand All @@ -87,26 +81,22 @@ func (mp *MemPool) Realloc(buf []byte, size int) []byte {
}

// Append .
//
//go:norace
func (mp *MemPool) Append(buf []byte, more ...byte) []byte {
return append(buf, more...)
}

// AppendString .
//
//go:norace
func (mp *MemPool) AppendString(buf []byte, more string) []byte {
return append(buf, more...)
}

// Free .
//
//go:norace
func (mp *MemPool) Free(buf []byte) {
mp.incrFree(buf)
if cap(buf) > mp.freeSize {
return
if buf != nil && cap(buf) > 0 {
mp.incrFree(buf)
if cap(buf) > mp.freeSize {
return
}
mp.pool.Put(&buf)
}
mp.pool.Put(&buf)
}
9 changes: 7 additions & 2 deletions nbhttp/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type BodyReader struct {
left int // num of byte left
buffers [][]byte // buffers that storage HTTP body
engine *Engine // allocator that manages buffers
closed bool
}

// Read reads body bytes to p, returns the num of bytes read and error.
Expand Down Expand Up @@ -56,13 +57,17 @@ func (br *BodyReader) Read(p []byte) (int, error) {
//
//go:norace
func (br *BodyReader) Close() error {
if br.closed {
return nil
}
br.closed = true
if br.buffers != nil {
for _, b := range br.buffers {
br.engine.BodyAllocator.Free(b)
}
}
*br = emptyBodyReader
bodyReaderPool.Put(br)
// *br = emptyBodyReader
// bodyReaderPool.Put(br)
return nil
}

Expand Down
2 changes: 2 additions & 0 deletions nbhttp/body_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func TestBodyReader(t *testing.T) {
if !bytes.Equal(allBytes, body1) {
t.Fatalf("!bytes.Equal(allBytes, body1)")
}
br1.Close()

br2 := newBR()
body2 := make([]byte, len(allBytes))
Expand All @@ -72,4 +73,5 @@ func TestBodyReader(t *testing.T) {
if !bytes.Equal(allBytes, body2) {
t.Fatalf("!bytes.Equal(allBytes, body2)")
}
br2.Close()
}
4 changes: 4 additions & 0 deletions nbhttp/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func releaseRequest(req *http.Request, retainHTTPBody bool) {
// do not release the body
} else {
br.Close()
*br = emptyBodyReader
bodyReaderPool.Put(br)
}
} else if !retainHTTPBody {
req.Body.Close()
Expand All @@ -74,6 +76,8 @@ func releaseClientResponse(res *http.Response) {
if res.Body != nil {
br := res.Body.(*BodyReader)
br.Close()
*br = emptyBodyReader
bodyReaderPool.Put(br)
}
*res = emptyClientResponse
clientResponsePool.Put(res)
Expand Down

0 comments on commit fd8d727

Please sign in to comment.