Skip to content

richImage may freeze the application in some cases. #3510

@alexballas

Description

@alexballas

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

I have an application where in one tab I have some richtext with an image and in another tab I have a drop down menu where you can select different themes for the application. If I open the application for the first time and I DONT click on the tab that has the rich text, I can change the theme from the other tab without issues, consistently.
If I click on the richtext tab and go back to select the theme from the dropdown, the application might freeze after I choose a theme. (this is intermittent behaviour)

So this is what happens when I select a theme

  1. (c *glCanvas) MinSize() calls RLock and then c.canvasSize(c.content.MinSize())
  2. The type of c.content in this case is container.AppTabs
  3. (t *AppTabs) MinSize() calls t.BaseWidget.MinSize().
  4. The type of BaseWidget is *widget.textRenderer
  5. inside (r *textRenderer) MinSize() there is a for loop for range bound.segments. One of the objects in that loop is widget.richImage
  6. (r *richImage) MinSize() calls internal.ScaleInt(c, orig.Width)
  7. internal.ScaleInt calls c.Scale(). c is a fyne.Canvas interface which with reflect I checked that is the glfw.glCanvas type.
  8. (c *glCanvas) Scale() calls RLock

Step 8 tries to get RLock but step 1 has not released it yet.

I managed to replicate the same issue in a much simpler example. Please check the provided code below. The application will freeze after a few seconds.

How to reproduce

Refer to the Go code below.

Screenshots

No response

Example code

package main

import (
	"time"

	fyne "fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)

var currentmfolder string

func main() {

	myApp := app.New()
	myWindow := myApp.NewWindow("Test Dialog")
	l := widget.NewLabel("hello")
	rich := widget.NewRichTextFromMarkdown(`![test](SOME_IMAGE_HERE.png)`)
	cont := container.NewVBox(l, rich)
	myWindow.SetContent(cont)

	go func() {
		for i := 0; i < 1000; i++ {
			go func() { fyne.CurrentApp().Settings().SetTheme(theme.DarkTheme()) }()
			time.Sleep(500 * time.Millisecond)
			go func() { fyne.CurrentApp().Settings().SetTheme(theme.LightTheme()) }()
			time.Sleep(500 * time.Millisecond)
		}
	}()

	myWindow.ShowAndRun()
}

Fyne version

v2.3.0

Go compiler version

1.19.4

Operating system

Linux

Operating system version

Ubuntu 18.04

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingracesIssues relating to race condition in Fyne

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions