commit 8da8bfc2fa3fcce7958093e99235ec3290ccb578
parent 9c52d53929fd1a8d8ea54a4777022af9a8221753
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Wed, 15 Mar 2023 14:54:44 +0800
internal/bind: avoid re-initializing windows runtime
Reinit causes errors (eg subsequent invocations of RoInitialize).
This logic will retry on error though, to maximize recoverability.
Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Diffstat:
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/internal/bind/bind.go b/internal/bind/bind.go
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"path/filepath"
+ "sync"
"syscall"
"unicode/utf16"
"unsafe"
@@ -72,13 +73,37 @@ func ConfigureRegistry(appID, appDisplayName, backgroundColor, exePath string) e
return nil
}
+var initLock sync.Mutex
+var didInitialize bool
+
+// initialize attempts to initialize the Windows Runtime.
+// Each invocation will retry RoInitialize until a successful initialization
+// is achieved. Once initialized, we avoid invoking RoInitialize since subsequent
+// reinitialization generates errors.
+func initialize() (err error) {
+ initLock.Lock()
+ defer initLock.Unlock()
+
+ if didInitialize {
+ return nil
+ }
+
+ if err := ole.RoInitialize(1); err != nil {
+ return fmt.Errorf("RoInitialize: %w", err)
+ }
+
+ didInitialize = true
+
+ return nil
+}
+
// GenerateToast notification via the specified xml content.
//
// No validation is performed on this xml content and the caller assumes responsibility
// for ensuring it's validity.
func GenerateToast(appID, xml string) error {
- if err := ole.RoInitialize(1); err != nil {
- return fmt.Errorf("RoInitialize: %w", err)
+ if err := initialize(); err != nil {
+ return err
}
xmlStr, err := syscall.UTF16PtrFromString(xml)