I'm using the X11::Protocol package to grab an image from the display, which I then shrink into a thumbnail using ImageMagick. The problem is that in certain cases, usually involving the X11 session shutting down while my script is running, my script seems to go into an infinite loop, using 100% CPU.
I believe I have traced this down to a bug in the X11::Protocol::Socket module, but before I report the bug, I want to run it by you experts.
In X11/Protocol/Connection/Socket.pm, I found this code:
sub get { my($self) = shift; my($len) = @_; my($x, $n, $o) = ("", 0, 0); my($sock) = $$self; until ($o == $len) { $n = $sock->sysread($x, $len - $o, $o); croak $! unless defined $n; $o += $n; } return $x; }
Clearly the purpose of this routine is to read a complete X11 response, which includes a header with the size of the rest of the response. In my case I'm calling the X11 function GetImage on the entire display, so the response is rather large. (It is not compressed.)
I believe the issue is that when the X11 server (the display) exits, the sysread() that my script calls will not return an error, but will instead return a 0, which means EOF. This will cause the "until" loop to never end, assuming sysread will continue to return 0 every time it is called after returning 0 once.
If this is what is happening, it would seem that fix would be to add this line after the "croak" line:
croak "end of file" unless $n;
Does that sound reasonable?
By the way, this file is on CPAN.
Update: I found that someone else reported this bug 8 years ago!
In reply to Bug in X11::Protocol::Socket? by Steve in Sunnyvale
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |