Skip Menu |

This queue is for tickets about the Linux-Inotify2 CPAN distribution.

Report information
The Basics
Id: 27122
Status: rejected
Priority: 0/
Queue: Linux-Inotify2

People
Owner: Nobody in particular
Requestors: ac56 [...] soas.ac.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: select() and inotify->(poll|read)()
Date: Mon, 14 May 2007 16:10:57 +0100
To: bug-Linux-Inotify2 [...] rt.cpan.org
From: Alexander Clouter <ac56 [...] soas.ac.uk>
Hi, I thought I had discovered a bug however I think its more a 'feature' of the UNIX select() function that becomes apparent when using it with the fileno of the inotify object. I have attached an example perl script that monitors for changes to a file in the current working directory called 'cheese'. When changed it spits out output from Data::Dumper on the return array of $inotify->read however when you press Ctrl-C it should gracefully exit from the core while() loop. Now originally[1] I found that I needed to press Ctrl-C twice or wait for an inotify event to occur before it would actually exit. After thinking that maybe $inotify->read simply pulls out the contents of the event queue rather than clearing it I slapped in a following $inotify->poll to find that was not the case. So, looking deeper into the problem I noticed in the perlfunc manpage for select() says: Note: on some Unixes, the select(2) system call may report a socket file descriptor as "ready for reading", when actually no data is available, thus a subsequent read blocks. It can be avoided using always the O_NONBLOCK flag on the socket. See select(2) and fcntl(2) for further details. This explains why the select() statement always comes back saying there is data lurking in the the event queue. To resolve this problem I set the object to be non-blocking and added an 'if ( @inotifyEvents )' to check there is content lurking in the event queue. Fortunately due to the workings of select() it does still block until something does happen to the $reader or event queue so everything works just nicely. I have not tested it but I am guessing your Event->io and Glib::IO examples also 'break' similarly and its worth putting in some documentation to explain this. If you could mention that[2] after the select()/Event->io/Glib::IO a check for actual queue content should be done and why that should be so would be great. Feel free to include my code as an example, I like to think it gives a good example, without adding additional perl module dependencies, of how to make an event based system rather than a timer polled while() loop. Cheers for an otherwise excellent module. Alex [1] before the setting of $inotify to be non-blocking and the 'if ( @inotifyEvents )' check were not present in the original code [2] if I am right and not similar gotten my code horribly wrong and thus am wasting your time ;)

Message body is not shown because sender requested not to inline it.

CC: undisclosed-recipients: ;
Subject: Re: [rt.cpan.org #27122] select() and inotify->(poll|read)()
Date: Tue, 19 Jun 2007 14:24:02 +0200
To: Alexander Clouter via RT <bug-Linux-Inotify2 [...] rt.cpan.org>
From: Marc Lehmann <schmorp [...] schmorp.de>
On Mon, May 14, 2007 at 11:12:09AM -0400, Alexander Clouter via RT <bug-Linux-Inotify2@rt.cpan.org> wrote: Show quoted text
> Note: on some Unixes, the select(2) system call may report a socket > file descriptor as "ready for reading", when actually no data is > available, thus a subsequent read blocks.
1. the manpage is wrong. 2. no socket is in involved here. Show quoted text
> This explains why the select() statement always comes back saying there is > data lurking in the the event queue.
Are you sure? I do not see you checking for an error in select, so the behaviour would be clearly explained by calling read(2) when select did not, in fact, do anything except return an error (most likely EINTR when you use SIGINT). Show quoted text
> To resolve this problem I set the object to be non-blocking and added an 'if
Managing non-blockedness is indeed a user thing. If your event loop calls read even though no data is waiting, you need to manage o_nonblock yourself. This is a valid way to go about things, but entirely your responsibility. If your main loop isn't buggy, then there is no need to use non blocking mode. Show quoted text
> Fortunately due to the workings of select() it does still block until > something does happen to the $reader or event queue so everything works just > nicely.
Right, and it still returns an error if interrupted. Show quoted text
> I have not tested it but I am guessing your Event->io and Glib::IO examples > also 'break' similarly and its worth putting in some documentation to explain > this.
I doubt it. Neither Event nor afaik Glib are buggy w.r.t. to signalling "ready"-ness when select didn't say so. Show quoted text
> If you could mention that[2] after the select()/Event->io/Glib::IO a > check for actual queue content should be done and why that should be so would > be great.
I have zero evidence for that being needed. Show quoted text
> Feel free to include my code as an example, I like to think it gives a good > example, without adding additional perl module dependencies, of how to make > an event based system rather than a timer polled while() loop.
Indeed, but you should first add error handling to make it robust, and then check to see wether you still need nonblocking operation. Show quoted text
> [2] if I am right and not similar gotten my code horribly wrong and thus am > wasting your time ;)
I wish the whole world would not continuously spread wrong information about non blocking mode and how it interacts with e.g. select/read or write. We wouldn't have bugs such as IO::Socket setting nonblocking mode per default unless the author weren't confused about how it works, just as you were by that wrong comment in the manpage. To quote the unix specification: Upon successful completion, the pselect() or select() function shall modify the objects pointed to by the readfds, writefds, and errorfds arguments to indicate which file descriptors are ready for reading, ready for writing, or have an error condition pending, respectively, and shall return the total number of ready descriptors in all the output sets. select(2) sets the read bit *precisely* *iff* a following read will be able to return data. While this is not specified for inotify filehandles, they behave the same. Think about it - select() would be totally broken if it sometimes returned false data. And as such, time was wasted - yours and mine, but its ok, at least one soul less should be confused about it :) The only lesson you should learn is: if you do not do proper error checking and it breaks you got to keep the pieces. If you want to learn even more, remember this: blocking mode *is* useful, blocking mode *makes* sense, blocking mode *does* work with select/poll as expected, blocking mode *does* work with read/write as expected (although you are advised to read and understand the susv w.r.t. read/write, as expectations sometimes differ between people and read/write do not have an obviously intuitive behaviour :) Greetings, PS: please do not use the perl bug tracking system but instead the address from the manpage, the perl bts is a PITA to use for authors. -- The choice of a -----==- _GNU_ ----==-- _ generation Marc Lehmann ---==---(_)__ __ ____ __ pcg@goof.com --==---/ / _ \/ // /\ \/ / http://schmorp.de/ -=====/_/_//_/\_,_/ /_/\_\ XX11-RIPE
please use the normal bug reporting address.