FLTK logo

Re: [fltk.general] FLTK in a secondary thread

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: FLTK in a secondary thread Ian MacArthur Oct 01, 2022  
 
Hi Rob,


On 1 Oct 2022, at 01:03, Rob McDonald wrote:
> 
> My C++ FLTK application is wrapped with SWIG to be available form Python.  This is normally done in a non-GUI way.  We are trying to enable the GUI while keeping access via Python.
> 
> If you initialize the GUI and then start the FLTK event loop from Python, the GUI will open and operate properly (tested on Windows and MacOS).  Of course, Python is blocked until control is returned.  If you stop the event loop (without terminating everything else), control is returned to Python.  You can re-start the event loop and return control to FLTK.
> 
> This works so far.  You can have the application GUI in a 'blocking' mode -- either the GUI is responsive, or Python can work.
> 
> We are working to make the GUI available in a non-blocking mode.  To do this, we need to compile the SWIG wrapper with the -threads option -- thereby the program gets and releases the Python GIL (global interpreter lock) as appropriate.
> 
> Then, if we start the application GUI up in a Python thread, the GUI seems to work, and Python can continue.  This seems to work fine on Windows.
> 
> However, on MacOS, when the GUI is being initialized in a secondary thread, execution hangs on a call to:
> 
> Fl::screen_xywh( x, y, w, h );
> 
> If that call is commented out, we instead hang a few lines later on a call to:
> 
> Fl_Sys_Menu_Bar::add()
> 
> In the FLTK documentation, it says:
> 
> Key amongst these is that, for many of the target platforms on which FLTK is supported, only the main() thread of the process is permitted to handle system events, create or destroy windows and open or close windows. Further, only the main() thread of the process can safely write to the display.
> 
> I think I might be running into this problem.


Yes, I think it almost certainly is.

Further, I’d caution that the Windows version, which is “working”, probably isn’t.
Anecdote time: years ago, a colleague had an app that ran fltk from a non-main thread and their “proof” that it was OK was they has been using it on their dev machine for weeks with no issues. Then it was deployed, and a flood of weird, unrelated, errors started being reported from the field. The app wasn’t working, it just looked like it was due to where random corruptions in memory were falling. Impossible to debug.
Once he fixed the threads, all was well...

> How can I know if this is the problem I am experiencing?

Don’t know of any robust indicator - on Windows, the side-effect seems to be random unrelated corruptions in memory, and maybe vary with GPU driver or some such. If the Windows version works on one machine but is flaky on another with different GPU or RAM size, that might be a clue of sorts.

> If I am hitting this problem, what will it take to get FLTK to work in the thread created for it by Python?

Re-writing fltk from the ground up, basically, and then figuring out how to interact safely with the graphics layer from multiple threads without corrupting the context.
It might be possible, but I don’t think it is an afternoons work... possibly a *bit* longer than that.
Note, for example, that for historical reasons fltk has quite a lot of global state that’d need to be handled, then the graphics context needs to be figured out, and...

> 
> Is there any way to make the new thread the 'main' thread?

Not really. You’d need to start the fltk app and have it spawn the python thread.
I do not know, but since python is only, effectively, one thread with a global lock, that should work. Probably.

Or have a wrapper program that launches your python code in one thread, then starts up fltk in the current (main) thread.

Or run it all in one thread, but never call Fl::run(); If you can contrive for your python code to call Fl::wait(0);  fairly often, that is all that is needed to keep fltk responsive.
How often constitutes “fairly often” is left as an exercise for the reader...

> 
> What would happen if someone wanted to use some other GUI with a separate event loop in the main Python thread?

Not sure I understand the question...?



-- 
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/3CDB72CB-984F-459C-8AF0-4DFDEA36DD5E%40gmail.com.
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.