Skip to content

Deadlock in Button CreateRenderer() #5114

Closed
@williambrode

Description

Checklist

  • I have searched the issue tracker for open issues that relate to the same problem, before opening a new one.
  • This issue only relates to a single bug. I will open new issues for any other problems.

Describe the bug

UI can deadlock due to acquiring the same read lock twice in a single goroutine. If any other goroutine acquires the same lock for write between the two reads - the second read will hang and never release the first, meaning the entire UI deadlocks.

Here is the sequence that causes the double read lock:

#	0xe91ce4	sync.runtime_SemacquireRWMutexR+0x24							runtime/sema.go:82
#	0x14de187	sync.(*RWMutex).RLock+0x47								sync/rwmutex.go:70
#	0x14de163	fyne.io/fyne/v2/widget.(*BaseWidget).Visible+0x23					fyne.io/fyne/[email protected]/widget/widget.go:85
#	0x14a2a6d	fyne.io/fyne/v2/widget.(*buttonRenderer).updateIconAndText+0x2d				fyne.io/fyne/[email protected]/widget/button.go:396
#	0x14a14af	fyne.io/fyne/v2/widget.(*Button).CreateRenderer+0x4cf					fyne.io/fyne/[email protected]/widget/button.go:123
#	0x11892d7	fyne.io/fyne/v2/internal/cache.Renderer+0x117						fyne.io/fyne/[email protected]/internal/cache/widget.go:33
#	0x14de0f0	fyne.io/fyne/v2/widget.(*BaseWidget).MinSize+0x30					fyne.io/fyne/[email protected]/widget/widget.go:74
#	0x14a166e	fyne.io/fyne/v2/widget.(*Button).MinSize+0x2e						fyne.io/fyne/[email protected]/widget/button.go:148
#	0x1243181	fyne.io/fyne/v2/layout.hBoxLayout.MinSize+0x101						fyne.io/fyne/[email protected]/layout/boxlayout.go:203
#	0x11776b0	fyne.io/fyne/v2.(*Container).MinSize+0x50						fyne.io/fyne/[email protected]/container.go:90
#	0x124254a	fyne.io/fyne/v2/layout.(*borderLayout).MinSize+0x2aa					fyne.io/fyne/[email protected]/layout/borderlayout.go:91
#	0x11776b0	fyne.io/fyne/v2.(*Container).MinSize+0x50						fyne.io/fyne/[email protected]/container.go:90
#	0x124489a	fyne.io/fyne/v2/layout.stackLayout.MinSize+0x9a						fyne.io/fyne/[email protected]/layout/stacklayout.go:47
#	0x11776b0	fyne.io/fyne/v2.(*Container).MinSize+0x50						fyne.io/fyne/[email protected]/container.go:90
#	0x1242ba1	fyne.io/fyne/v2/layout.vBoxLayout.MinSize+0x101						fyne.io/fyne/[email protected]/layout/boxlayout.go:120
#	0x11776b0	fyne.io/fyne/v2.(*Container).MinSize+0x50						fyne.io/fyne/[email protected]/container.go:90
#	0x123a364	fyne.io/fyne/v2/internal/widget.(*SimpleRenderer).MinSize+0x24				fyne.io/fyne/[email protected]/internal/widget/simple_renderer.go:46

(*Button).CreateRenderer takes the propertyLock.RLock(), and so does (*BaseWidget).Visible which is further down the stacktrace.

How to reproduce

It is a race condition so it will be hard to reproduce without modifying the code to enforce the ordering that causes the deadlock. It is easy to see from the code that the possibility of deadlock exists. In my case - the thread waiting on the write lock was trying to call .Hide() on the button.

Screenshots

No response

Example code

No code needed.

Fyne version

2.5.0

Go compiler version

1.19.3

Operating system and version

Windows 10

Additional Information

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions