int main() {
..
Fl::lock(); // lock without an unlock() tells fltk to enable locking
return Fl::run();
}
int main() {There's no chance of someone getting confused by this code.
..
Fl::enable_locks();
return Fl::run();
}
The more I look at it, the more this looks like a bug in someone's applcation code:
int main() {
..
Fl::lock(); // lock without an unlock() tells fltk to enable locking
return Fl::run();
}
While that's apparently the "right way" to inform FLTK the app is going to use locking, it looks wrong and feels wrong for app code to have a lock() without an unlock().
I'd like to suggest we make a simple wrapper function called:
Fl::enable_locks();
Underneath that might just call Fl::lock(), but at least then the user's app code looks clearer:
int main() {
..
Fl::enable_locks();
return Fl::run();
}
Comments?
On 4/17/21 8:01 AM Greg Ercolano wrote:
While that's apparently the "right way" to inform FLTK the app is going to use locking, it looks wrong and feels wrong for app code to have a lock() without an unlock().
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;
}
;-)
As others have said already, I also wouldn't mind adding such a function. Other method names might be:
Fl::start_lock();
Fl::use_lock();
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) {...}
Another option might be to use Fl::option(ENABLE_LOCKING);
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...
..seems unclear offhand. I'm trying to propose something so
the code reads clearly
what it does without comments.
--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/c315ce11-cec6-88cd-49d4-efdbd524546a%40online.de.
On 4/17/21 6:03 PM Greg Ercolano wrote:
On 4/17/21 4:36 AM, Albrecht Schlosser wrote:
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.
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.)
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.
On Apr 17, 2021, at 1:00 PM, Albrecht Schlosser <Albrech...@online.de> wrote:
On 4/17/21 2:25 PM Michael Sweet wrote:Another crazy option: just have Fl::lock() be a no-op if the run loop is not active and then have Fl::run() call Fl::lock() unconditionally. When threading is enabled (which should be all the time now) the right thing happens without any special initialization, and Fl::lock()/unlock() can continue to be used for synchronization as before.
Mike, IIRC there's still the "side effect" that the first call into Fl::lock() enables the locking and unlocking feature. Hence, if you never call it, locking and unlocking will not be done by the FLTK thread (event loop), which is probably one of "fast and light" design aspects of FLTK.
#include <stdio.h>#include <time.h>#include <sys/time.h>#include <pthread.h>int main(void){struct timeval start, end;int i;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;double secs;gettimeofday(&start, NULL);for (i = 0; i < 1000000000; i ++){pthread_mutex_lock(&mutex);pthread_mutex_unlock(&mutex);}gettimeofday(&end, NULL);secs = end.tv_sec - start.tv_sec + 0.000001 * (end.tv_usec - start.tv_usec);printf("%.3f seconds\n", secs);return (0);}
--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/649B330D-C92B-441B-B9A0-E8E46EF8260A%40gmail.com.
On 4/18/21 6:48 AM, Michael Sweet wrote:
So honestly, the overhead of using threading locks, even for a single-threaded program, is so small that I would recommend that we make FLTK thread-safe by default.
--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/13b64cf2-659e-c0ad-5d15-908194b80f88%40seriss.com.