Well, there's no problem, you can also write
int main() {
..
Fl::lock(); // lock FLTK (this) thread
int ret = Fl::run();
Fl::unlock(); // unlock
return ret;
}
;-)
LOL, that just looks worse -- it looks like we're locking out child
threads from the entire app loop.
Yes, and that's what it is doing. See it this way: before you start the
FLTK event loop with Fl::run() you set a FLTK lock in the main thread.
You could then start other threads that are locked out from FLTK access
and would block if they call Fl::lock(). You could also create widgets
and windows here (after locking FLTK) in the main thread before you
execute Fl::run().
Then the FLTK event loop /releases/ the lock /temporarily/ while it has
nothing to do (during Fl::wait()) so other threads waiting for the lock
can access FLTK objects. After Fl::wait() the main FLTK thread acquires
the lock again, does its job, and finally releases it before it waits again.
Calling Fl::lock() in the main thread is NOT different than calling it
in any other place (as you say: an "overload"). It only has the side
effect that the /first/ execution of Fl::lock() enables locking
internally (no matter when or where you call it). At least that's what I
believe.
Calling Fl::unlock() after Fl::run() is basically useless (but could be
done) because the program exits anyway. But there could be other
scenarios...
An alternative and IMHO clean way to clarify things would be to add an
optional argument to Fl::run():
static int Fl::run(int enable_locks = -1) {...}
Oh, that's an interesting idea.
But hmm, what if there's other features we need to enable in the
future? Add them as arguments too?
Have we ever needed an extra feature in Fl::run() in the last 22 years? ;-)
Might be better to be a separate method with the name 'lock' in it,
so it can appear
in the threading docs along with the other lock related methods.
Just RTFM: Fl::lock() and Fl::unlock() ;-)
Another option might be to use Fl::option(ENABLE_LOCKING);
-1
Fl::option() is "overloaded" with too many features and an ugly
interface (IMHO). It does also use preferences which would be bad here.
(Does it? I'm not sure.)
The more I think about it, the more I like the latter, i.e. adding
such a parameter to Fl::run().
And FLTK 1.4 would be a good place to start this...
I like the idea if C++ supported named arguments like in python, e.g.
Fl::run(enable_locks = 1);
But to just have:
Fl::run(1);
..seems unclear offhand. I'm trying to propose something so the
code reads clearly what it does without comments.
Honestly? Sorry, I disagree.
<joke>
#define RUN_WITH_LOCKS 1
Fl::run(RUN_WITH_LOCKS);
</joke>
Seriously: there are lots of functions with one or more parameters that
might not be absolutely clear w/o accessing the documentation. If
Fl::run(int use_lock) (or 'enable_locks' as I suggested before) is
well-documented, then there should be no doubt.
Here are just two examples of methods with "unclear" parameters
(actually three because the first uses an overload):
Please don't understand me wrong, I'm open for all kinds of
implementations (except maybe Fl::option()) but it was just that I could
not follow your argumentation.
Comments are owned by the poster. All other content is copyright 1998-2025 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.