mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-13 15:46:49 +03:00
Make sure removed/resetted user valeus get garbage collected
Since our userData slice isn't shrunk when we delete values, it can still keep pointing to things that have been removed. Set these pointers to nil so that the key and value can be garbage collected. Fixes https://github.com/valyala/fasthttp/issues/1812
This commit is contained in:
@@ -77,6 +77,8 @@ func (d *userData) Reset() {
|
||||
if vc, ok := v.(io.Closer); ok {
|
||||
vc.Close()
|
||||
}
|
||||
(*d)[i].value = nil
|
||||
(*d)[i].key = nil
|
||||
}
|
||||
*d = (*d)[:0]
|
||||
}
|
||||
@@ -92,6 +94,7 @@ func (d *userData) Remove(key any) {
|
||||
if kv.key == key {
|
||||
n--
|
||||
args[i], args[n] = args[n], args[i]
|
||||
args[n].key = nil
|
||||
args[n].value = nil
|
||||
args = args[:n]
|
||||
*d = args
|
||||
|
||||
@@ -3,7 +3,9 @@ package fasthttp
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestUserData(t *testing.T) {
|
||||
@@ -118,3 +120,32 @@ func TestUserDataSetAndRemove(t *testing.T) {
|
||||
testUserDataGet(t, &u, []byte(shortKey), "")
|
||||
testUserDataGet(t, &u, []byte(longKey), "")
|
||||
}
|
||||
|
||||
func TestUserData_GC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var u userData
|
||||
key := "foo"
|
||||
final := make(chan struct{})
|
||||
|
||||
func() {
|
||||
val := &RequestHeader{}
|
||||
runtime.SetFinalizer(val, func(v *RequestHeader) {
|
||||
close(final)
|
||||
})
|
||||
|
||||
u.Set(key, val)
|
||||
}()
|
||||
|
||||
u.Reset()
|
||||
runtime.GC()
|
||||
|
||||
select {
|
||||
case <-final:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("value is garbage collected")
|
||||
}
|
||||
|
||||
// Keep u alive, otherwise val will always get garbage collected.
|
||||
u.Set("bar", 1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user