4. Threads and Communication
Some of the actions which need to be performed during the installation process, such as scanning disks for existing partitions or downloading package metadata, can take a long time. To prevent you from waiting and remain responsive if possible, Anaconda runs these actions in separate threads.
The Gtk toolkit does not support element changes from multiple threads. The main event loop of Gtk runs in the main thread of the Anaconda process itself, and all code performing actions which involve the GUI must make sure that these actions are run in the main thread as well. The only supported way to do so is by using the GLib.idle_add
, which is not always easy or desired. To alleviate this problem, several helper functions and decorators are defined in the pyanaconda.ui.gui.utils module.
The most useful of those are the @gtk_action_wait
and @gtk_action_nowait
decorators. They change the decorated function or method in such a way that when this function or method is called, it is automatically queued into Gtk's main loop, run in the main thread, and the return value is either returned to the caller or dropped, respectively.
As mentioned previously, one of the main reasons for using multiple threads is to allow the user to configure some screens while other screens which are currently busy (such as Installation Source when it downloads package metadata) configure themselves. Once the configuration is finished, the spoke which was previously busy needs to announce that it is now ready and not blocked; this is handled by a message queue called hubQ
, which is being periodically checked in the main event loop. When a spoke becomes accessible, it sends a message to this queue announcing this change and that it should no longer be blocked.
The same applies in a situation where a spoke needs to refresh its status or completion flag. The Configuration and Progress hub has a different queue called progressQ
which serves as a medium to transfer installation progress updates.
These mechanisms are also needed for the text-based interface, where the situation is more complicated; there is no main loop in text mode, instead the majority of time in this mode is spent waiting for keyboard input.