go-sciter icon indicating copy to clipboard operation
go-sciter copied to clipboard

Is calling sciter functions from another goroutine safe?

Open dodobyte opened this issue 6 years ago • 4 comments

I call tiscript functions from a seperate goroutine, not the gui one. Is this allright? If not how can i call them in gui thread. After w.Run() i lost control of the gui.

If there's a mechanism to run code in gui thread like a callback or message handler, i would appreciate any information about it.

Also should i lock gui OS thread with runtime.LockOSThread()?

dodobyte avatar Apr 18 '18 14:04 dodobyte

  1. You can call UI (by UI I mean DOM elements and their methods in HTML) from any thread, almost all API functions are thread safe. In fact, they will be executed in GUI thread automatically.

  2. You can also store script functions in sciter.Value and call them later from goroutines or OS threads.

As for the LockOSThread - I think, you don't have to call it.

pravic avatar Apr 18 '18 15:04 pravic

Great, Thank you.

dodobyte avatar Apr 18 '18 16:04 dodobyte

If there's a mechanism to run code in gui thread like a callback or message handler, i would appreciate any information about it.

Could you describe your case? When do you want to create a new window? Usually it is done either in the beginning (main window) or in reaction of some event (e.g button click).

pravic avatar Apr 19 '18 04:04 pravic

Could you describe your case?

I have a job that takes long time (would hang the gui) so i run it in another goroutine and update GUI from that goroutine. In windows you cannot update GUI from another thread, you may pass a message to GUI message queue so the update is done by the GUI thread. Every GUI library i've worked with had this limitation since the GUI is a shared resource.

If sciter queues GUI calls to run on GUI thread implicitly, there should not be a problem for my case.

I believe the cause of the panic is related to my second question (about runtime.LockOSThread()).

Since Go has it's own scheduler for goroutines, it switches the goroutine which created the GUI to another OS thread anytime it wants.

This causes trouble for almost every graphics related libraries. The solution is to lock GUI goroutine to underlying OS thread. Thus the GUI related codes will always run on the same OS thread.

So i believe runtime.LockOSThread() is necessary and should solve the problem.

references: https://golang.org/pkg/runtime/#LockOSThread https://github.com/golang/go/wiki/LockOSThread

edit: You were right about sciter queuing GUI calls to run on GUI thread. https://sciter.com/making-api-thread-safe/

The only problem left is go switching GUI goroutine to antoher OS thread, this init code guarantees that won't happen.

func init() {
	runtime.LockOSThread()
}

Of course the main goroutine should create the window.

dodobyte avatar Apr 19 '18 04:04 dodobyte