Skip to content

win32: Window.buffer manipulation is racy, can panic on minimisation #52

Description

@sqweek

I've seen it panic once when minimising a window, like so:

panic: runtime error: index out of range

goroutine 51 [running]:
github.com/AllenDang/w32.SetDIBitsToDevice(0xfffffffff4013245, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5969d0, ...)
        C:/src/go/src/github.com/AllenDang/w32/gdi32.go:471 +0x10a
github.com/skelterjohn/go.wde/win.(*Window).blitImage(0xc04206a280, 0xfffffffff4013245, 0xc0430b29c0)
        C:/src/go/src/github.com/skelterjohn/go.wde/win/win_windows.go:217 +0x13a
github.com/skelterjohn/go.wde/win.(*Window).FlushImage(0xc04206a280, 0x0, 0x0, 0x0)
        C:/src/go/src/github.com/skelterjohn/go.wde/win/win_windows.go:176 +0x1b4
github.com/sqweek/goui/wdedrv.WdeDrv.Flip(0x562b80, 0xc04206a280)
        C:/code/go/src/github.com/sqweek/goui/wdedrv/wdedrv.go:22 +0x53
github.com/sqweek/goui/wdedrv.(*WdeDrv).Flip(0xc0420080b0)
        <autogenerated>:2 +0x5d
github.com/sqweek/goui.(*Painter).Loop(0xc0420740a0)
        C:/code/go/src/github.com/sqweek/goui/paint.go:70 +0xf9
created by main.wdemain
        C:/code/go/src/github.com/sqweek/goui/example/worms/worms.go:99 +0x2d3

It's index 0:

gdi32.go:471:                 uintptr(unsafe.Pointer(&lpvBits[0])),

lpvBits corresponds to buffer.Pix in Window.blitImage, indicating that we have a zero-length pixel array. FlushImage tries to avoid this scenario (since #46):

func (this *Window) FlushImage(bounds ...image.Rectangle) {
        if this.buffer.Bounds().Empty() {
                return // happens when window is minimised
        }

So I guess this.buffer must be changing concurrently. I'm calling FlushImage from a different goroutine than the one handling EventChan but I think it's racy even without that since Window.buffer is changed when WndProc handles a WM_SIZE message, before the ResizeEvent is posted. Even the EventChan thread may observe the change to buffer before seeing the ResizeEvent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions