-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve go-webview2 com object release #3931
Comments
The reference count returned from Microsoft also states https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release#return-value
So I personally would not change the signature to return uint32, which would basically then always be ignored in the Wails code. Also changing the interface means we should probably bump go-webview2 to v2 so people won't end up with a brocken Wails application by the means of just calling a We should probably just leave the interface (and change the implementation to return nil in go-webview2) as it is so we don't break all the Wails v2 apps out there. Then clearly define a set of rules how errors should be handled and detected for com call and afterwards bring go-webview2 as v2 up to that and use it in Wails v3. @leaanthony any thoughts? |
Agree with you @stffabi . We don't want past decisions to hold us back so let's create a v2 directory and create what we think is the right API in there. I started looking at the composition controller too and realised that the main components of the package should probably change too. The code generator needs to be updated to output the better error handling. |
@Snshadow - given we can create a new v2 version of this library, what are your recommendations? Shall we just copy what's there for now and make the additional breaking changes above? |
I think that we could leave the Addref() and Release() return an error as it were before, we could check the reference count of a object then return an error if the functions are called on a object which reference count has reached zero after usage.
func (c *comObject) release() int32 {
c.l.Lock()
defer c.l.Unlock()
if c.refCount <= 0 {
panic("call on destroyed com object")
}
...
}
Instead, we could add a refCount field in the COM object structs of keep track of reference count when calling AddRef or Release after QueryInterface to prevent any undefined behaviours(exception, crash, ...), then increment the refCount value with type _ICoreWebView2WebResourceResponseVtbl struct {
_IUnknownVtbl
GetContent ComProc
PutContent ComProc
GetHeaders ComProc
GetStatusCode ComProc
PutStatusCode ComProc
GetReasonPhrase ComProc
PutReasonPhrase ComProc
refCount uint32
}
func (i *ICoreWebView2WebResourceResponse) AddRef() error {
if i.refCount <= 0 {
return fmt.Errorf("called Addref() on object with reference count zero")
}
v, _, _ := i.vtbl.AddRef.Call(uintptr(unsafe.Pointer(i)))
_ = v // do something with this value for debugging/testing purpose?
i.refCount++
return nil
}
func (i *ICoreWebView2WebResourceResponse) Release() error {
if i.refCount <= 0 {
return fmt.Errorf("called Release() on object with reference count zero")
}
v, _, _ := i.vtbl.Release.Call(uintptr(unsafe.Pointer(i)))
_ = v // do something with this value for debugging/testing purpose?
i.refCount--
return nil
} The return value of AddRef or Release can be used only in some situations as https://learn.microsoft.com/en-us/windows/win32/com/rules-for-managing-reference-counts states that
Next, for the function that could return |
Please be aware of the differences between the combridge and the other com code. The combridge is used to implement com-objects in go, there we implement com-interfaces in go, that get passed to com. So the real com-object is managed in Go. The combridge is currently only used in rare cases for bootstrapping the webview2, where we need to create and pass a com-object to webview2. Whereas e.g. As for the panic you mentioning for |
@stffabi Oh, there are lots of things that were going on behind the scene.., thank you for the explanation!
which indicates an access violation when I accidentally called Release after ole.VARIANT.Clear() while using the go-ole package which calls VariantClear as it calls Release for however, as wails and go-webview2 implements the use of COM object itself, the checking the reference count would not be necessary if AddRef() and Release() are used with care. |
This is a followup from wailsapp/go-webview2#25 (comment) which couldn't be fixed properly as
wails build
fails in Windows if it were changed.The cause of the build failure is due to these codes that expects error return from Release function which only returns reference count as a uint32 value, not an error, which can cause unexpected erroring as Proc.Call states that
These parts expect Release to return an error which prevent building from succeeding.
wails/v2/pkg/assetserver/webview/request_windows.go
Lines 125 to 127 in 6345b64
wails/v2/pkg/assetserver/webview/request_windows.go
Lines 135 to 137 in 6345b64
wails/v2/pkg/assetserver/webview/request_windows.go
Lines 155 to 161 in 6345b64
If this were to be fixed, wails and go-webview2 would need to be fixed at the same time(as wails depends on go-webview2).
The text was updated successfully, but these errors were encountered: