PDA

View Full Version : How to integrate asio::io_service with Qt event loop?



niXman
9th February 2013, 15:19
Hi,

I need to call asio::io_service:: poll_one() (http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/io_service/poll_one/overload1.html) in Qt event loop.
I googled similar questions, but they do not have distinct answers.
Links to examples are welcome.

Thanks.

niXman
10th February 2013, 18:45
Is there anybody alive?

d_stranz
10th February 2013, 19:46
Of course we're alive. Probably no one here has done what you're trying to do. Neither have I, but you could try this:

Write your own loop in whatever QObject-based class needs to poll the asio instance. In this loop, call QCoreApplication:: processEvents() and then call your asio:: poll_one() method. It would probably be smart to implement the handler in such a way that it does not do any processing itself, but simply emits a signal with the arguments (or the arguments packed into a struct). This way, the actual handling of the poll is done within the Qt even loop.

peper0
14th December 2014, 23:46
You may be interested in my qtasio (https://github.com/peper0/qtasio). It's an implementation of QAbstractEventDispatcher for boost::asio.

All you need is to add the following line before creating QApplication (usually it's in main()).


QApplication::setEventDispatcher(new QAsioEventDispatcher(my_io_service));

It makes io_service being run together with qt application in one thread without additional latency and performance drop (like in solutions with calling io_service::poll() "from time to time").

Unfortunately, my solution is for posix systems only, since it use asio::posix::stream_descriptor . Windows support may need completely different approach or quite similar - I don't really know.

anda_skoa
15th December 2014, 08:54
I am not so sure that replacing the main thread's event dispatcher is a good idea for any application that is QGuiApplication or QApplication based.

In these cases the event dispatcher for the main thread is usually provided by the platform abstraction plugin and might to a lot more than the base dispatcher for the current operating system (e.g. window system event integration)

Depending on platform it might not even be a good idea for a QCoreApplication based program, since the used dispatcher can depend on build time and runtime choices (e.g. GLib event loop integration on Unix systems).

Cheers,
_

wysota
15th December 2014, 09:16
I am not so sure that replacing the main thread's event dispatcher is a good idea for any application that is QGuiApplication or QApplication based.

In these cases the event dispatcher for the main thread is usually provided by the platform abstraction plugin and might to a lot more than the base dispatcher for the current operating system (e.g. window system event integration)

Depending on platform it might not even be a good idea for a QCoreApplication based program, since the used dispatcher can depend on build time and runtime choices (e.g. GLib event loop integration on Unix systems).


I had exactly the same impression after reading the post and looking at the code.

peper0
15th December 2014, 12:03
Ok. So why there is a Glib version of QAbstractEventDispatcher? Why integration with Glib is better than with boost::asio?

anda_skoa
15th December 2014, 13:16
Ok. So why there is a Glib version of QAbstractEventDispatcher?

Not sure what you mean.

Most likely there was a need for it and somebody implemented and upstreamed it.

Presumably because there are or were GLIb event loop based libraries that somebody wanted to use in a singlethreaded Qt application.



Why integration with Glib is better than with boost::asio?

Do you mean "why is it better integrated" or "why does the integration work better"?

Cheers,
_

wysota
15th December 2014, 14:02
Ok. So why there is a Glib version of QAbstractEventDispatcher? Why integration with Glib is better than with boost::asio?

One thing could be that it integrates well with GStreamer.

peper0
15th December 2014, 15:23
Sorry for being not clear enough.

I proposed to integrate boost::asio "mainloop" with qt by the means of reimplementing event dispatcher. This is exactly how qt is integrated with Glib. You said, that my proposition is wrong because of some reasons:


I am not so sure that replacing the main thread's event dispatcher is a good idea for any application that is QGuiApplication or QApplication based.

In these cases the event dispatcher for the main thread is usually provided by the platform abstraction plugin and might to a lot more than the base dispatcher for the current operating system (e.g. window system event integration)

Depending on platform it might not even be a good idea for a QCoreApplication based program, since the used dispatcher can depend on build time and runtime choices (e.g. GLib event loop integration on Unix systems).

I understand that my solution is not very flexible and it would not work out-of-box on other platforms. I understand also, that my boost::asio integration contradict other external event loop integration (like GLib event loop). However, in my opinion, QEventDispatcherGlib has the same drawbacks, but it's not considered to be a bad idea.

Therefore, I'm wondering why reimplementing QAbstractEventDispatcher for glib is a good idea and reimplementing it for boost::asio is wrong?

I'm not very deeply involved in QT, so maybe I'm missing something obvious.

wysota
15th December 2014, 15:32
Glib integration was implemented for Qt (and made the default event loop) as an improvement over a bare unix event dispatcher as it is the most commonly used event loop on unix systems. Usually you'd want to complement that lib instead of replacing it.

anda_skoa
15th December 2014, 19:36
I proposed to integrate boost::asio "mainloop" with qt by the means of reimplementing event dispatcher. This is exactly how qt is integrated with Glib. You said, that my proposition is wrong because of some reasons:

No, the troublesome part is not the event dispatcher implementation, but the way it gets "installed".
In QGuiApplication program the QPA will be asked to create the main loop's event dispatcher, i.e. so that it can integrate window event handling when this is different to how the base platform dispatcher works.

E.g. integrate with the X11 event system on Unix, or the libscreen system on QNX.



However, in my opinion, QEventDispatcherGlib has the same drawbacks, but it's not considered to be a bad idea.

It would be a bad idea as well if it were to be used by overwriting the event dispatcher needed by the application.

But it is not.



Therefore, I'm wondering why reimplementing QAbstractEventDispatcher for glib is a good idea and reimplementing it for boost::asio is wrong?

The difference is how the dispatcher is integrated, not what it does.
The boost::asio could even be better implementation wise for all that I know.



I'm not very deeply involved in QT, so maybe I'm missing something obvious.

The approach of providing an application specific event dispatcher is fine for any secondary thread, but potentially highly problematic on the main thread.
Especially in a gui application.

Cheers,
_