Receiving Signals in Qt5

I’ve been reviewing some Qt5 modules and ran into an issue that doesn’t seem to have an obvious solution. Inside a constructor, I create and run a Qt5 object. However, since exec() is called within this object, the constructor never completes—it gets blocked inside exec(). As a result, the signal mechanism and RPC don’t function properly.

Is there a proper way to handle this, or am I forced to use a separate thread to manually check for updates from a signal-emitting object, making direct signal reception impossible?

The solution I found for this issue is to handle the creation of a Qt5 widget inside a separate thread so that the constructor is properly closed. However, to ensure that signals are received correctly, I had to use Libc::with_libc([&] in the signal handling function.

That said, I think if the Component structure were extended to include a run or make function alongside the constructor, developers could use this approach to resolve blocking issues more effectively. Additionally, this might make memory management and resource handling more predictable.

If I understand your QObject implementation correctly, the blocking behavior must be expected. Transferfing this scenario to a POSIX system, an application not returning from the QObject constructor is not able to call select() on any open file/socket descriptor not known to Qt outside the QObject scope. Thus for example. any open socket will never be examined for incoming connections or packets.

In my opinion, you should reconsider to change your design and proxy Genode signals to Qt signals. You may have a look into genode/repos/gems/src/test/tiled_wm/util.h at master · genodelabs/genode · GitHub for an example proxy implementation and genode/repos/gems/src/test/tiled_wm/panel at master · genodelabs/genode · GitHub for a Qt app using this feature.

Note, you’re perfectly right about the Libc::with_libc in a Genode signal handler, because the (main) entrypoint thread currently must explicitly switch into its Libc context. This is currently missing in the proxy above, but was unnoticed until now as the signal handler just triggers a Qt::QueuedConnection.

1 Like