GNOME Bugzilla – Bug 540489
"zenity --list" w/ input from regular file uses 100% CPU
Last modified: 2011-07-08 14:59:18 UTC
Please describe the problem: "zenity --list" uses 100% CPU while it waits for me to click OK or Cancel in the list dialog. Running it under strace reveals that it is trying furiously to read more list entries from stdin even after it has gotten EOF. Steps to reproduce: 1. zenity --list --column=Column </dev/null Actual results: Zenity uses 100% CPU. Expected results: Zenity uses a reasonable amount of CPU. Does this happen every time? Yes. Other information: Bug 336478 is a similar problem with the --progress option.
I figured out what is going on here. Zenity relies on G_IO_HUP to tell it when it is done reading the input. This works fine for a pipe. However, if stdin is a regular file, zenity gets a condition of G_IO_IN and a status of G_IO_STATUS_EOF, hits the "continue" and tries to read over and over again. (Although the stdin feature was meant to be used with a pipe, I'll argue that using a regular file is a reasonable thing to do if the input is too large to be passed as arguments or needs to be kept secret from other users, who can view arguments via ps.) This is straightforward to fix: instead of "continue"-ing, shut down the input channel. There's a second case in which zenity uses 100% CPU: if a partial line is piped to it, it enters a tight loop of calling g_io_channel_read_line_string (which returns immediately with G_IO_STATUS_AGAIN) and processing any events. To reproduce: (echo -n 'Hello'; sleep 5; echo ' world!') | zenity --list --column=Foo This looks harder to fix. Please tell me if I should enter a separate bug.
Created attachment 113739 [details] [review] Fixes bug 540489 and bug 540560 This patch fixes bug 540489 (100% CPU upon hitting the end of a regular file) and bug 540560 (loss of the end of the input) for both --list and --progress. I took the opportunity to eliminate the code duplication in zenity_tree_handle_stdin and zenity_progress_handle_stdin by replacing them with a common stdin-handling function, zenity_util_stdin_io_func, that calls back to functions specific to the list and progress modes. This patch does not fix the issue with 100% CPU on a partial line, for which I will enter a separate bug.
See also #510496
Hello, This patch didn't work correctly, even I removing all the outdated partes (ex: using glade_xml_* functions.) Could you please submit a new patch?
This is very similar to bug #541001, and It's fixed with a call to g_usleep in the while loop waiting for status != G_IO_STATUS_AGAIN. The logic here is, instead of be in this loop over and over waiting for read the line, we read the line, run one loop on gtk main, wait a bit and check the status. Now, every time it goes in the loop, it take a break (not so slow that human can notice, and not so fast that makes no difference). This keep the cpu usage very slow (checking on top 0.3 - 0.7 cpu usage)
A fix was commited in master.