On Thu, 21 May 2009 22:58:53 +0200 buergi <[email protected]> wrote:
> perhaps someone could explain how the Dispatcher works, not in code > but what happens behind the scenes. when i emit the dispatcher in the > worker thread, when does the connected function in the main thread get > executed. will it be called by the signal handling in the gtk main > loop? > > the only problem is that i cannot pass arguments over a > Glib::Dispatcher neither return values are supported (of course since > the dispatcher is asynchronously). I also need to pass the content of > variables from one thread to the other. > What about a SigCX::ThreadTunnel? When you emit on a Glib::Dispatcher object, in unix-like OSs it sends a key (actually it's the dispatcher's address) on a pipe which has a watch on the pipe's file descriptor attached to the main program event loop which executes in the main GUI thread. On windows it signals a windows event object, likewise plumbed into the main loop. The slot(s) you have connected to the Dispatcher object will then be executed in the main GUI thread whenever you emit on the dispatcher, which is what you want. It will be executed by the main loop on its next event iteration. You don't need to worry about "when" (it will be "shortly after, depending on what else is in the event queue") - if you do need to worry about it, threads are probably not the answer to the problem you are programming for. To pass arguments using Glib::Dispatcher, except in very simple cases you will probably need something like an asynchronous queue. glibmm doesn't have one, but it is relatively straightforward to make your own based on std::queue and Glib::Mutex, and I can send the one I use if it helps - there are certain subtleties to be observed if you want the queue to retain strong exception safety. Alternatively you can use g_idle_add() or g_idle_add_full(), which are thread safe as with the rest of glib, and these also add events, in the form of a callback, to the event queue in the main loop. The callback function should strictly speaking have C linkage, although in fact g++ allows you to use static member functions which have C++ linkage (but if you want standards conformance you should use a callback function declared extern C, and make it a friend if you need it to have private/protected class access). You can pass any arguments you like as the data argument to g_idle_add() - typically it might just be the address of the class object that you want the callback to be able to access - but if it is more than that you will probably need to pass a data struct by address with the data allocated on the heap and freed in the callback once finished with. The callback function should return false so that it only executes once. Using g_idle_add() is the most directly analogous approach to using windows events, passing messages to the the windows GDI for drawing (basically it works exactly the same way). Don't be fooled by the name, which was a poor choice - if you use g_idle_add_full() you can choose any priority in the event queue you like. The disadvantage is that you do not get the safety arising from automatic slot disconnection when using Glib::Dispatcher with slots representing methods of classes deriving from sigc::trackable. With g_idle_add(), it is for you to make sure that when the main loop executes the callback, any class object it is accessing still exists. On the other hand you don't have to worry about the validity of a Glib::Dispatcher object, which must exist when a slot is executed via a dispatcher (the main loop tries to look up the dispatcher object on slot execution for obvious reasons). Note that you cannot use Glib::signal_idle() from glibmm for this, as unfortunately it is not thread safe. I've never used SigCX but I think it also uses pipes, connected to the main loop. Chris _______________________________________________ gtkmm-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/gtkmm-list
