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  }