I didn't dig too deep into the sigc docs, but the gtkmm multithreading
<https://developer.gnome.org/gtkmm-tutorial/stable/sec-the-constraints.html.en>
documentation seemed clear enough to me after the coffee kicked in :)

First it states clearly
> Use Glib::Dispatcher to invoke gtkmm functions from worker threads

Then it says
> only the thread in which a main loop runs should call
Glib::SignalIdle::connect()

The problem here is that I don't want to connect to every idle signal, I
want a function to run once on the next idle. As you said, you can't
connect in the worker thread to add that connect_once(). The important part
is that the function is run (connected) once, not setup as a signal that is
continuously being called every time the idle signal fires.

You mentioned running the lambdas in signal_idle, but how do you get the
lambdas there in the first place? The function that calls the lambdas in
signal_idle needs prior knowledge of where the lambas live to actually run
them. You need some kind of a thread safe queue to get them there, no?
That's basically what the code I wrote addresses.

I think that it should be possible to simply call g_idle_add with a
std::function and no need for any queueing because from docs
<https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-idle-add>
it seems like (hard to tell honestly) it should be safe to use from worker
threads. I haven't seen anything like that in gtkmm though. The rust
bindings have glib::idle_add in that manner, so I'm guessing we can do the
same here.

Best,
-Ben

On Fri, Sep 11, 2020 at 8:00 AM <gtkmm-list-requ...@gnome.org> wrote:

> Send gtkmm-list mailing list submissions to
>         gtkmm-list@gnome.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.gnome.org/mailman/listinfo/gtkmm-list
> or, via email, send a message with subject or body 'help' to
>         gtkmm-list-requ...@gnome.org
>
> You can reach the person managing the list at
>         gtkmm-list-ow...@gnome.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of gtkmm-list digest..."
>
>
> Today's Topics:
>
>    1. Invoking GTK main thread from other threads (Benjamin Quinn)
>    2. Re: Invoking GTK main thread from other threads (Daniel Boles)
>    3. Re: Invoking GTK main thread from other threads (Daniel Boles)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 10 Sep 2020 12:40:54 -0400
> From: Benjamin Quinn <benlqu...@gmail.com>
> To: gtkmm-list@gnome.org
> Subject: Invoking GTK main thread from other threads
> Message-ID:
>         <CAL7GaSmu3HxFCuFzeBwWOjw2X8Ei3vBrdvnm4eHZ=-
> khvg1...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> Hey all,
>
> I've been working on a project using gtkmm and I was looking at the
> multithreading docs. It seems that the recommended way to send data to the
> UI thread is to use a Gtk::Dispatcher to signal data has changed and a
> mutex to synchronize that data.
>
> Using other bindings, such as GTK#, you have callback methods available to
> run a function on the main thread, which can be safely invoked from other
> threads.
>
> I created a simple implementation of this for gtkmm here
> <https://github.com/Blquinn/idlequeue>. The architecture is described in
> the readme.
>
> Let me know what you all think, or if there's any huge issues with it, I'm
> new to c++ development, so there's a good chance this is not safe at all.
>
> Best,
> -Ben
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> https://mail.gnome.org/archives/gtkmm-list/attachments/20200910/aca828ba/attachment.html
> >
>
> ------------------------------
>
> Message: 2
> Date: Thu, 10 Sep 2020 18:29:58 +0100
> From: Daniel Boles <dboles....@gmail.com>
> To: gtkmm-list <gtkmm-list@gnome.org>
> Subject: Re: Invoking GTK main thread from other threads
> Message-ID:
>         <CAKChMKMsoLoGHYqrPfrJ9yVkEuVh7aKhw--0hyzLS_SMzD=
> o...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> from your readme:
>
> > GTK# and other gtk bindings supply a method to callback to the main
> thread, which gtkmm does not.
>
> I'm pretty sure it does. Or rather, GLib does, and GTK uses the GLib main
> loop, and glibmm/gtkmm wrap both of those.
>
> You simply connect to Glib::signal_idle(), passing a callback, which will
> be called once the GLib main loop is running and has nothing of a higher
> priority to do.
>
> https://developer.gnome.org/glibmm/stable/classGlib_1_1SignalIdle.html
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> https://mail.gnome.org/archives/gtkmm-list/attachments/20200910/a566efde/attachment.html
> >
>
> ------------------------------
>
> Message: 3
> Date: Thu, 10 Sep 2020 18:35:45 +0100
> From: Daniel Boles <dboles....@gmail.com>
> To: gtkmm-list <gtkmm-list@gnome.org>
> Subject: Re: Invoking GTK main thread from other threads
> Message-ID:
>         <
> cakchmkncdcoyb2qe8ie9wepotwtkxjz5hgflvkvl_hoekio...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> That said, it's equally possible I am wrong and SignalIdle technically is
> not thread-safe. I can't really make sense of the wording in the docs...
>
> for connect_once(), we have:
>
> > Because sigc::trackable
> <
> http://library.gnome.org/devel/libsigc++/unstable/structsigc_1_1trackable.html
> >
> is not thread-safe, if the slot represents a non-static method of a class
> deriving from sigc::trackable
> <
> http://library.gnome.org/devel/libsigc++/unstable/structsigc_1_1trackable.html
> >,
> and the slot is created by sigc::mem_fun()
> <
> http://library.gnome.org/devel/libsigc++/unstable/group__mem__fun.html#gadf6b6d22c503b439019f0a2e77352419
> >,
> connect_once()
> <
> https://developer.gnome.org/glibmm/stable/classGlib_1_1SignalIdle.html#a94217dc63e35f96b5cee4c48f2cdd020
> >
> should only be called from the thread where the SignalIdle
> <https://developer.gnome.org/glibmm/stable/classGlib_1_1SignalIdle.html>
> object's MainContext
> <https://developer.gnome.org/glibmm/stable/classGlib_1_1MainContext.html>
> runs. You can use, say, boost::bind() or, in C++11, std::bind()
> <
> http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01513.html#ga7b2eddb726568256e49824ad01a05099
> >
> or a C++11 lambda expression instead of sigc::mem_fun()
> <
> http://library.gnome.org/devel/libsigc++/unstable/group__mem__fun.html#gadf6b6d22c503b439019f0a2e77352419
> >
> .
>
> That makes enough sense and still leaves plenty cases for which it'll
> definitely be safe.
>
> but for connect(), we have the unconditional:
>
> > This method is not thread-safe. You should call it, or manipulate the
> returned sigc::connection
> <
> http://library.gnome.org/devel/libsigc++/unstable/structsigc_1_1connection.html
> >
> object, only from the thread where the SignalIdle
> <https://developer.gnome.org/glibmm/stable/classGlib_1_1SignalIdle.html>
> object's MainContext
> <https://developer.gnome.org/glibmm/stable/classGlib_1_1MainContext.html>
> runs.
>
> I would expect the same condition(s) to apply to connect() as to
> connect_once() - since AFAIK, all the once version does is just disconnect
> itself automatically - but I might just be missing some obvious reason why
> this can't be the case. And now I feel like maybe I've had this discussion
> in the past...!
>
> Anyway, I mentioned it because I have had the usual crashy behaviour
> symbolic of trying to access widgets in threads other than the main one, in
> my own projects, and wrapping the code doing said accesses in a lambda run
> in SignalIdle has always fixed it. Maybe I've just been lucky so far?
>
> Thoughts/corrections to me from those more experienced at doing
> multi-threading with gtkmm are welcome.
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> https://mail.gnome.org/archives/gtkmm-list/attachments/20200910/f86e8bcc/attachment.html
> >
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtkmm-list
>
>
> ------------------------------
>
> End of gtkmm-list Digest, Vol 196, Issue 1
> ******************************************
>
_______________________________________________
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to