views:

12

answers:

0

I've been successfully reading the Linux file '/proc/self/mounts' from within a Ruby thread using stock Ruby in Ubuntu Lucid (ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]). Now I'm trying to do the same on Red Hat 5.5 (ruby 1.8.6 (2010-02-05 patchlevel 399) [x86_64-linux]), but the thread won't complete. I wrote a testing script to demonstrate:

#!/usr/bin/env ruby
start = Time.now
file_path = ARGV[0]
print "testing access of #{file_path}\n"

# verify access to file
print "top begin time: #{Time.now - start}\n"
print "has #{File.readlines(file_path).length} line(s)\n"
print "top complete time: #{Time.now - start}\n"

# now read it from within a ruby thread
t = Thread.new{ 
        print "thread begin time: #{Time.now - start}\n"
        print "has #{File.readlines(file_path).length} line(s)\n"
        print "thread complete time: #{Time.now - start}\n" 
}

# is thread done?
5.times{ |i|
        sleep 1
        print "status #{i} begin time: #{Time.now - start}\n"
        print "current status is: '#{t.status}'\n"
        if t.status
                print "*** MANUALLY INTERVENING WITH t.run\n"
                t.run
        else
                break
        end
        print "status #{i} end time: #{Time.now - start}\n"
}

# now read it again outside a ruby thread
print "bottom begin time: #{Time.now - start}\n"
print "has #{File.readlines(file_path).length} line(s)\n"
print "bottom complete time: #{Time.now - start}\n"

The output on Ubuntu for a file in /proc:

ubuntu:~$ /tmp/io_test.rb /proc/self/sched
testing access of /proc/self/sched
top begin time: 9.6e-05
has 46 line(s)
top complete time: 0.000401
thread begin time: 0.00436
has 46 line(s)
thread complete time: 0.004817
status 0 begin time: 1.005669
current status is: 'false'
bottom begin time: 1.005768
has 46 line(s)
bottom complete time: 1.005981

The output on Ubuntu for /proc/self/mounts:

ubuntu:~$ /tmp/io_test.rb /proc/self/mounts
testing access of /proc/self/mounts
top begin time: 8.7e-05
has 29 line(s)
top complete time: 0.000538
thread begin time: 0.017905
has 29 line(s)
thread complete time: 0.019292
status 0 begin time: 1.019565
current status is: 'false'
bottom begin time: 1.019659
has 29 line(s)
bottom complete time: 1.02003

The output on Red Hat for a harmless file in /proc:

redhat:~$ /tmp/io_test.rb /proc/self/schedstat 
testing access of /proc/self/schedstat
top begin time: 8.0e-05
has 1 line(s)
top complete time: 0.000219
thread begin time: 0.000282
has 1 line(s)
thread complete time: 0.000422
status 0 begin time: 1.000754
current status is: 'false'
bottom begin time: 1.000807
has 1 line(s)
bottom complete time: 1.000855

The output on Red Hat for /proc/self/mounts (note the two "sleep" status lines):

redhat:~$ /tmp/io_test.rb /proc/self/mounts
testing access of /proc/self/mounts
top begin time: 0.000119
has 18 line(s)
top complete time: 0.000359
thread begin time: 0.000469
status 0 begin time: 1.001455
current status is: 'sleep'
*** MANUALLY INTERVENING WITH t.run
status 0 end time: 1.001659
status 1 begin time: 2.002439
current status is: 'sleep'
*** MANUALLY INTERVENING WITH t.run
has 18 line(s)
thread complete time: 2.002506
status 1 end time: 2.002525
status 2 begin time: 3.002415
current status is: 'false'
bottom begin time: 3.002446
has 18 line(s)
bottom complete time: 3.00253

So the question is: why am I having problems reading only /proc/self/mounts, only on Red Hat, and only from within a thread? How can I read the file without manually waking up the thread?