Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to integrate Boost.Asio main loop in GUI framework like Qt4 or GTK

Is there any way to integrate Boost.Asio with Qt4 (preferred) or GTK main loop? GTK provides poll(2) like API so technically is should be possible. Qt provides its own networking layer, however I prefer to use existing code written for Boost.Asio. I want to integrate them without using an additional thread.

Is there any reference how to do this for Qt4 (preferred) or GTKmm?

Thanks.

Edit

I want to clearify several things to make the answer easier. Both Qt and GTKmm provide "select like" functionality:

  • http://qt-project.org/doc/qt-5.0/qtcore/qsocketnotifier.html
  • http://www.gtkmm.org/docs/glibmm-2.4/docs/reference/html/group__MainLoop.html

So, the question is, how to integrate existing "selectors/pollers" as reactor to Boost.Asio io_service. Today, Boost.Asio can use select, kqueue, epoll, /dev/poll and iocp as reactor/proactor service. I want to integrate it to the main-loop of GUI framework.

Any suggestions and solutions (better) are welcome.

like image 421
Artyom Avatar asked Jun 16 '09 11:06

Artyom


1 Answers

Simple: Build a QT slot that calls the io_service::poll_one() belonging to the gui. Connect that slot to QT's tick signal.

In Depth: Luckily for you Boost.Asio is very well designed. There are many options on how to provide a thread of execution to the underlying asynchronous internals. People have already mention using io_service::run(), a blocking call with many disadvantages.

You are only allowed to access gui widgets from a single thread. External threads generally need to post events to the gui if they want to do mutate any widget. This is very similar to how Asio works.

The naive approach is to just dedicate one thread (or timer) to running io_service::run() and have the Asio completion handler post a gui signal. This will work.

Instead you can use the guarantee that completion handlers will only be called in the thread of execution of the io_service caller. Don't have the gui thread call io_service::run() as it is blocking and could hang the gui. Instead use io_service::poll() or io_service::poll_one(). This will cause any pending Asio completion handlers to be called from the gui thread. Since the handlers are running in the gui thread they are free to modify the widgets.

Now you need make sure the io_service gets a chance to run regularly. I recommend having a repeating gui signal call poll_one() a few times. I believe QT has a tick signal that would do the trick. You could of course roll your own QT signal for more control.

like image 164
deft_code Avatar answered Oct 06 '22 00:10

deft_code