Re: [fltk.general] API access to FLTK app

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: API access to FLTK app Rob McDonald 10:42 Jan 15 top right image
 
On Saturday, January 15, 2022 at 8:41:45 AM UTC-8 spitzak wrote:
FLTK already has a lock exactly like this. Calling code (for instance your python wrappers for any fltk functions) should lock before calling anything.

There is a hack so if nobody calls the lock() it does not interfere with the operation of a single-threaded program, which is probably why you don't know it exists.

Calling Fl::run() or other functions that process events is pretty much the "start the gui" call. Whatever thread does this will become the main thread as far as fltk is concerned.

As you know, there are unfortunately a bunch of fltk calls that assume they are running in the main thread, especially on Windows. Grabbing the lock does not help. It would be nice to fix this but it is unusual that you have to work around it, in particular because any callbacks will execute in the main thread.

If you want a callback to run python code you must grab the Python GIL.

On Sat, Jan 15, 2022 at 3:32 AM Ian MacArthur wrote:

Hi Rob,

On 15 Jan 2022, at 06:53, Rob McDonald wrote:
>
> To do this, I think we need to...
>
> Add a StartGUI() routine to the API that will start a new thread, open the default GUI windows, and start the event loop (basically do what main() does for the interactive program).  The original thread will return control to Python.
>
> Add a lock that prevents truly simultaneous access.  Whenever an event comes in, FLTK must acquire the lock before calling into my code to handle the event.  Once the event is fully handled (and control returns to the event loop), the lock is released.
>
> At the same time, every API call must acquire the lock before doing anything.  The lock will be released when the API call is finished.
>
> Acquiring the lock will be blocking -- whether from the GUI or the API, if the program is busy, you'll see some lag or hesitation.  However, much of the time, you will be able to interact normally with the program.
>
> Is this the right idea?  Do I have a fundamental misunderstanding here?  Can anyone point at an example application that takes this approach?
>
> Thanks in advance for any help,


I think the idea is OK, but I’m uncomfortable about the proposed implementation.
The crux, for me, is that this ends up with the fltk GUI context running in a “non-main” thread - and that, basically, is not going to be robust, I fear.

A lot (some | many | most) systems are such that the GUI context “belongs" to the main thread of a process, and GPU drivers are built for speed, not safety, and the result is that modifying the GUI context from a non-main thread can be “fragile”, though the fragility can vary from GPU to GPU. (The usual manifestation of this is bugs or crashes “elsewhere” in the program due to pointer corruptions etc. which can be insanely difficult to debug.)

Further, at least on Windows hosts, event delivery (at the OS level, not the fltk level) can be “tricky" to non-main threads.

If the Python thread *also* has a GUI, then things can get really nasty pretty quickly.

So: It might work (or at least appear to work, on some hosts, anyway) but I suspect it would just lead to pain.

Where I’ve done this in the past, I usually just spawn a whole new process and have the two processes communicate, e.g. via pipes or etc.
If this has to run on Win32 hosts as well, then I use (localhost) network sockets between the processes rather than pipes - this simply because the fltk Fl::add_fd() can pend on Windows network sockets, but not on Windows pipes (on Posix hosts add_fd() will happily listen to any suitable fd, it is only Win32 that is “weak” in this regard.)

FWIW, localhost network sockets on Win32 are cheap and high bandwidth, so it’s a pretty easy way to pass the IPC between the processes anyway - and has the advantage that, by simply setting the address to something other than 127.0.0.1 you can then split the app over two separate systems “for free” as it were.


Does it change anything that none of the code called from Python will be FLTK code?

I have no intention (for now at least) of having the C++ side (via a callback or otherwise) execute any Python code.

This does need to work on Windows, Linux, and MacOS.

Rob

 

--
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/4f049f09-d5d2-4178-bd3b-61b26bbdce57n%40googlegroups.com.
Direct Link to Message ]
 
bottom left image   bottom right image
Previous Message ]New Message | Reply ]Next Message ]
 
 

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