# Xrefresh server, rb-inotify and ioselect

**URL:** <https://www.ruby-forum.com/t/xrefresh-server-rb-inotify-and-ioselect/181594>\
**Category:** Ruby\
**Created:** [January 14, 2010, 10:04am UTC](https://www.ruby-forum.com/t/xrefresh-server-rb-inotify-and-ioselect/181594 "2010-01-14T10:04:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![willwach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/c68b51/32.png) [@willwach](https://www.ruby-forum.com/u/willwach)\
**Post date:** [January 14, 2010, 10:04am UTC](https://www.ruby-forum.com/t/xrefresh-server-rb-inotify-and-ioselect/181594/1 "2010-01-14T10:04:42Z")

</div>

Hi,

This is of interest for all Linux devs doing web development.

I patched the xrefresh server so that it runs on Linux. Not everything  
is implemented but it is useable:  
[http://github.com/MarcWeber/xrefresh-server](http://github.com/MarcWeber/xrefresh-server)  
Changes will be merged upstream soon.

The question I have is about IO.select line 97  
[http://github.com/MarcWeber/xrefresh-server/blob/linux/lib/xrefresh-server/linux/monitor.rb](http://github.com/MarcWeber/xrefresh-server/blob/linux/lib/xrefresh-server/linux/monitor.rb)

I think when running this app a long time I get bad file descriptor.  
When using a wait time of 0.01 I get this error message very soon.

Is this a known issue? I contacted the author of rb-inotify. He told me  
I should rewrite the io select loop using C and see whether the same  
problem occurs. However you may just know about this issue without me  
rewriting everything in C… In fact it doesn’t hurt me much. I’m  
just curious.

So is there someone who wants to try xrefresh on Linux and can verify  
this behaviour?

Note:  
You have to list each file you want to watch in the config path section.

Marc W.

PS: I am new to ruby so I may have done something obviously stupid.

---

<div class="post-metadata">

**Author:** ![willwach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/c68b51/32.png) [@willwach](https://www.ruby-forum.com/u/willwach)\
**Post date:** [January 14, 2010, 3:37pm UTC](https://www.ruby-forum.com/t/xrefresh-server-rb-inotify-and-ioselect/181594/2 "2010-01-14T15:37:08Z")

</div>

I’ve tracked it down:

This example

require ‘rb-inotify’  
notifier = INotify::Notifier.new

begin  
io = notifier.to\_io  
nr = 1  
while true  
nr = nr +1  
if IO.select([notifier.to\_io], [], [], 0.0001) # 0.01 yields "bad  
file descriptor!  
notifier.process  
end  
end

rescue  
puts “nr is #{nr}”  
end

outputs:

tmp i%for i in `seq 20`; do ruby test.rb; done  
/tmp nixos  
nr is 6768  
nr is 6768  
nr is 6770  
nr is 6768  
nr is 6770  
nr is 6768  
nr is 6768  
nr is 6770  
nr is 6768  
nr is 6768  
nr is 6768  
nr is 6768  
nr is 6768  
nr is 6769  
nr is 6768  
nr is 6769  
nr is 6768  
nr is 6768  
nr is 6770  
nr is 6769

So the problem occurs roughly after the same amount of to\_io calls.  
using lsof -p $THIS\_RUBY\_PROCESS it shows the file descriptor is gone!

When suspending the prog while there is no error looking at losf -p $PID  
output shows that file descriptor 3 is connected to inotify.  
So it must be notifier.to\_io which is causing trouble. I added a puts to  
verify that the file descriptor is always 3.

So my fix is easy: use notifier.to\_io to define a local var and use  
that local var within the IO.select loop. Then my problem is gone

Nathan: Can you recommend this example instead?

io = notifier.to\_io  
while true  
if IO.select([io], [], [], 0.0001)  
notifier.process  
end  
end

This seems to work. I’m still interested what’s causing this trouble.  
Obviously there is a problem with the to\_io code which looks like this:

def to\_io  
raise NotImplementedError.new(“INotify::Notifier#to\_io is not  
supported under JRuby”) if RUBY\_PLATFORM =~ /java/  
IO.new(@fd)  
end

So ruby doesn’t like callign IO.new(@fd) over and over again.

Is this a bug?

Marc W.

---

<div class="post-metadata">

**Author:** ![willwach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/c68b51/32.png) [@willwach](https://www.ruby-forum.com/u/willwach)\
**Post date:** [January 16, 2010, 1:49am UTC](https://www.ruby-forum.com/t/xrefresh-server-rb-inotify-and-ioselect/181594/3 "2010-01-16T01:49:40Z")

</div>

On Thu, Jan 14, 2010 at 8:36 AM, Marc W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This seems to work. I’m still interested what’s causing this trouble.  
> Obviously there is a problem with the to\_io code which looks like this:
> 
> Â def to\_io  
> Â Â raise NotImplementedError.new(“INotify::Notifier#to\_io is not supported under JRuby”) if RUBY\_PLATFORM =~ /java/  
> Â Â IO.new(@fd)  
> Â end
> 
> So ruby doesn’t like callign IO.new(@fd) over and over again.

If you create an IO object to wrap an fd, when it GCs it will close  
that fd. I’m not sure if there’s a way to “detach” from a given fd so  
it doesn’t close. You might prefer reopen instead of creating new IOs  
every time.

- Charlie
