3

How can I write a main loop which blocks while waiting for messages from multiple sources? As I understand it, the preferred way of writing an event-processing loop is to have it block while waiting for events.

However, how can blocking be handled correctly when messages may come from multiple sources?

I would like to write a GTK GUI which responds both to user input events and to messages sent via nanomsg.

GTK allows its events to be handled by calling gtk_main() or, in a non-blocking way, with gtk_main_iteration_do (FALSE).

Nanomsg can receive a message in either blocking or non-blocking mode, as well as poll for messages.

Is it possible to somehow block until whichever source first has input available "unblocks"? I.e. is there an alternative to using sleep which remains responsive to all events?

dhardy
  • 11,175
  • 7
  • 38
  • 46
  • Unfortunately GTK+ must exist entirely within one thread. I don't know if nanomsg has a way to integrate itself with GLib (and Google doesn't help), but as an alternative you can run nanomsg on another thread and use `g_add_idle()` or `gdk_threads_add_idle()` (one of the two; I forget which is better again) to schedule your UI updates on the UI thread. – andlabs May 15 '15 at 14:13
  • @andlabs I don't think that will work. If the passed function blocks, isn't it going to block user input events? If it doesn't block, isn't it going to loop causing high CPU usage, or else not be called frequently enough to get input immediately? ntd's answer looks more promising. – dhardy May 20 '15 at 12:05
  • Running nanomsg on another thread won't block user input events; those are all handled by the GTK+ thread. `idle_add()` schedules a function to be run when there's no input event pending; you can use this to update the UI in response to a message received by nanomsg (but don't actually do message handling here, otherwise what you said will happen). – andlabs May 20 '15 at 12:36

1 Answers1

3

You can have as many threads as you want in your GTK+ application (and you are not forced to use GMainLoop instances) provided that any call that modifies the UI happens in the main GTK+ loop.

In this answer I provided an example with 100 threads updating the same user interface.

At the end you can fork and use whatever you are more familiar with in your own thread (being it polling, blocking or whatever) and be careful only when you need to notify (i.e. modify the UI).

Community
  • 1
  • 1
ntd
  • 7,372
  • 1
  • 27
  • 44