mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
app/internal/window: [Windows] avoid race between Main and window closes
While here, replace the window hwnd-to-window map with a sync.Map. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -42,7 +42,9 @@ type window struct {
|
|||||||
|
|
||||||
const _WM_REDRAW = windows.WM_USER + 0
|
const _WM_REDRAW = windows.WM_USER + 0
|
||||||
|
|
||||||
var mainDone = make(chan struct{})
|
// windowCounter keeps track of the number of windows.
|
||||||
|
// A send of +1 or -1 represents a change in window count.
|
||||||
|
var windowCounter = make(chan int)
|
||||||
|
|
||||||
type gpuAPI struct {
|
type gpuAPI struct {
|
||||||
priority int
|
priority int
|
||||||
@@ -53,10 +55,8 @@ type gpuAPI struct {
|
|||||||
// implementations.
|
// implementations.
|
||||||
var backends []gpuAPI
|
var backends []gpuAPI
|
||||||
|
|
||||||
var winMap struct {
|
// winMap maps win32 HWNDs to *windows.
|
||||||
mu sync.Mutex
|
var winMap sync.Map
|
||||||
windows map[syscall.Handle]*window
|
|
||||||
}
|
|
||||||
|
|
||||||
var resources struct {
|
var resources struct {
|
||||||
once sync.Once
|
once sync.Once
|
||||||
@@ -68,12 +68,12 @@ var resources struct {
|
|||||||
cursor syscall.Handle
|
cursor syscall.Handle
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
winMap.windows = make(map[syscall.Handle]*window)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Main() {
|
func Main() {
|
||||||
<-mainDone
|
// Wait for first window
|
||||||
|
count := <-windowCounter
|
||||||
|
for count > 0 {
|
||||||
|
count += <-windowCounter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWindow(window Callbacks, opts *Options) error {
|
func NewWindow(window Callbacks, opts *Options) error {
|
||||||
@@ -88,19 +88,11 @@ func NewWindow(window Callbacks, opts *Options) error {
|
|||||||
}
|
}
|
||||||
defer w.destroy()
|
defer w.destroy()
|
||||||
cerr <- nil
|
cerr <- nil
|
||||||
winMap.mu.Lock()
|
winMap.Store(w.hwnd, w)
|
||||||
winMap.windows[w.hwnd] = w
|
windowCounter <- +1
|
||||||
winMap.mu.Unlock()
|
|
||||||
defer func() {
|
defer func() {
|
||||||
winMap.mu.Lock()
|
winMap.Delete(w.hwnd)
|
||||||
defer winMap.mu.Unlock()
|
windowCounter <- -1
|
||||||
delete(winMap.windows, w.hwnd)
|
|
||||||
if len(winMap.windows) == 0 {
|
|
||||||
select {
|
|
||||||
case mainDone <- struct{}{}:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
w.w = window
|
w.w = window
|
||||||
w.w.SetDriver(w)
|
w.w.SetDriver(w)
|
||||||
@@ -185,9 +177,10 @@ func createNativeWindow(opts *Options) (*window, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr {
|
func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr {
|
||||||
winMap.mu.Lock()
|
var w *window
|
||||||
w := winMap.windows[hwnd]
|
if win, exists := winMap.Load(hwnd); exists {
|
||||||
winMap.mu.Unlock()
|
w = win.(*window)
|
||||||
|
}
|
||||||
switch msg {
|
switch msg {
|
||||||
case windows.WM_UNICHAR:
|
case windows.WM_UNICHAR:
|
||||||
if wParam == windows.UNICODE_NOCHAR {
|
if wParam == windows.UNICODE_NOCHAR {
|
||||||
|
|||||||
Reference in New Issue
Block a user