github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/pkg/assetserver/webview/request_finalizer.go (about) 1 package webview 2 3 import ( 4 "runtime" 5 "sync/atomic" 6 ) 7 8 var _ Request = &requestFinalizer{} 9 10 type requestFinalizer struct { 11 Request 12 closed int32 13 } 14 15 // newRequestFinalizer returns a request with a runtime finalizer to make sure it will be closed from the finalizer 16 // if it has not been already closed. 17 // It also makes sure Close() of the wrapping request is only called once. 18 func newRequestFinalizer(r Request) Request { 19 rf := &requestFinalizer{Request: r} 20 // Make sure to async release since it might block the finalizer goroutine for a longer period 21 runtime.SetFinalizer(rf, func(obj *requestFinalizer) { rf.close(true) }) 22 return rf 23 } 24 25 func (r *requestFinalizer) Close() error { 26 return r.close(false) 27 } 28 29 func (r *requestFinalizer) close(asyncRelease bool) error { 30 if atomic.CompareAndSwapInt32(&r.closed, 0, 1) { 31 runtime.SetFinalizer(r, nil) 32 if asyncRelease { 33 go r.Request.Close() 34 return nil 35 } else { 36 return r.Request.Close() 37 } 38 } 39 return nil 40 }