[BUG] gtk blocks reading from a file (0.16.0)


#1

Hi,

I came across an other problem with ruby-gnome 0.16.

Reading files from the sysfs under linux seems impossible. Here is a
short example:

require “gtk2”

sysdir = ‘/sys/class/video4linux’
sysentries = Dir.new sysdir
sysentries.each do |s|
if s != ‘.’ and s != ‘…’ and File.directory?(sysdir + ‘/’ + s)
name_file = sysdir + ‘/’ + s + ‘/name’
if File.exist?(name_file) and File.readable?(name_file)
p File.new(name_file, “r”).gets.chomp
end
else
sensor_file = sysdir + ‘/’ + s + ‘/sensor’
if File.exist?(sensor_file) and File.readable?(sensor_file)
p File.new(sensor_file, “r”).gets.chomp
end
end
end

It looks if a video camera is connected and prints its name or the used
sensor. To the line where the file is opened ( File.new(name_file,
“r”) ) it works well. But in the “gets” method it hangs.

If i comment out the requiring of gtk2, or try to read from a regular
file it works like expected.

With ruby-gnome 0.14.* it gave no problems.

Cheers
detlef

Ps. big thanks to Kouhei S. for the fast fix of the libglade problem!


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#2

Le dimanche 31 décembre 2006 à 12:43 +0100, Detlef R. a écrit :

It looks if a video camera is connected and prints its name or the used
sensor. To the line where the file is opened ( File.new(name_file,
“r”) ) it works well. But in the “gets” method it hangs.

If i comment out the requiring of gtk2, or try to read from a regular
file it works like expected.

With ruby-gnome 0.14.* it gave no problems.

This reminds me the issue I got when reading procfs in threaded mode :

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/131871

Maybe something regarding threads changed in gtk2 init


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#3

Pascal T. [2006-12-31 13:35]:

This reminds me the issue I got when reading procfs in threaded mode :

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/131871

Maybe something regarding threads changed in gtk2 init

The problem is reproducable with just requiring glib2.

Regards,
Tilman


#4

Hi,

On Sun, 31 Dec 2006 12:43:42 +0100
Detlef R. removed_email_address@domain.invalid wrote:

sysentries = Dir.new sysdir
end

With ruby-gnome 0.14.* it gave no problems.

Could you show me more simple sample?

I don’t have video4linux interface so I couldn’t execute it.
And I tried the code below (pointed out by Pascal), It worked well.

% cat test.rb
require ‘gtk2’
puts File.readlines("/proc/cmdline")

% ruby -v test.rb
ruby 1.8.5 (2006-12-04 patchlevel 2) [x86_64-linux]
ro root=/dev/VolGroup00/LogVol00 rhgb quiet


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#5

Le jeudi 04 janvier 2007 à 19:24 +0100, Detlef R. a écrit :

I’ve attached 3 tests, 2 for the sysfs and one for the procfs. In the
sysfs it hangs and with proc it runs.

The 3 tests work fine here (i686, kernel 2.6.19.1, ruby 1.8.5, rg2
0.16.0)


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#6

On Do, 2007-01-04 at 19:24 +0100, Detlef R. wrote:
[selfquote]

ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-linux]
i will update to 1.8.5 and see if something changed

i’ve updated to ruby 1.8.5 and the errors remains. The same with ruby
1.9.0 - with ruby-gnome 0.14 it works, with 0.16 not.


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#7

Le vendredi 05 janvier 2007 à 01:16 +0100, Pascal T. a écrit :

Le jeudi 04 janvier 2007 à 19:24 +0100, Detlef R. a écrit :

I’ve attached 3 tests, 2 for the sysfs and one for the procfs. In the
sysfs it hangs and with proc it runs.

The 3 tests work fine here (i686, kernel 2.6.19.1, ruby 1.8.5, rg2
0.16.0)

OK, it hangs on my other machine (x86_64, kernel 2.6.17, ruby 1.8.5, rg2
0.16.0)

strace ruby -e ‘File.new("/sys/class/tty/tty/dev", “r”).gets’ gives

open("/sys/class/tty/tty/dev", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=4096, …}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x2ad4de2d3000
read(3, “5:0\n”, 4096) = 4

strace ruby -rglib2 -e ‘File.new("/sys/class/tty/tty/dev", “r”).gets’
gives
open("/sys/class/tty/tty/dev", O_RDONLY) = 5
select(6, [3 5], [], [], NULL

So, it looks like the threading issue I used to have on /proc but it
looks line /proc/cmdline now handles correctly select.
I guess now sysfs handles select while it did not in previous kernels.


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#8

On Do, 2007-01-04 at 11:54 +0900, Masao M. wrote:

Hi,

ruby 1.8.5 (2006-12-04 patchlevel 2) [x86_64-linux]
ro root=/dev/VolGroup00/LogVol00 rhgb quiet

it seems that the proc and the sysfs filesystems work different.

I’ve attached 3 tests, 2 for the sysfs and one for the procfs. In the
sysfs it hangs and with proc it runs.

ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-linux]
i will update to 1.8.5 and see if something changed

example 1

require “gtk2”
require “find”
sysdir = ‘/sys/class/’
Find.find sysdir do |path|
if path.match “.*/dev$”
if File.exist?(path) and File.readable?(path)
p “read #{path}”
p File.new(path, “r”).gets
end
end
end

example 2

require “gtk2”
require “find”
sysdir = ‘/sys/module/’
Find.find sysdir do |path|
if path.match “.*/srcversion$”
if File.exist?(path) and File.readable?(path)
p “read #{path}”
p File.new(path, “r”).gets
end
end
end

example within the proc tree

require “gtk2”
require “find”
procdir = ‘/proc/’

Find.find procdir do |path|
if path.match “.*/cmdline$”
if File.exist?(path) and File.readable?(path)
p “read #{path}”
p File.new(path, “r”).gets
end
end
end


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#9

Le vendredi 05 janvier 2007 à 01:41 +0100, Pascal T. a écrit :

0.16.0)
gives
open("/sys/class/tty/tty/dev", O_RDONLY) = 5
select(6, [3 5], [], [], NULL

So, it looks like the threading issue I used to have on /proc but it
looks line /proc/cmdline now handles correctly select.
I guess now sysfs handles select while it did not in previous kernels.

http://www2.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4508a7a734b111b8b7e39986237d84acb1168dd0


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#10

Hi,

On Mon, 8 Jan 2007 20:35:40 +0100
removed_email_address@domain.invalid (Sjoerd S.) wrote:

it seems that the proc and the sysfs filesystems work different.
require “find”
I could reproduce your problem with example 1.
ssize_t size;
}
we don’t need to fix this.
That will block forever on linux 2.6.18, but will return immediately on
2.6.19.1 (I’m not sure what the exact version this change was in).

Now my patch which uses a fifo to be notified of external signals. Which means
that there is always at least one readable fd and thus triggers this issue, but
it’s not the cause.

Thanks.
I think we don’t need to fix this problem now.

But if someone can fix this issue, show your patch to us.


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#11

Hi,

On Thu, 04 Jan 2007 19:24:00 +0100
Detlef R. removed_email_address@domain.invalid wrote:

On Do, 2007-01-04 at 11:54 +0900, Masao M. wrote:

Hi,

require “gtk2”
require “find”
sysdir = ‘/sys/class/’
Find.find sysdir do |path|
if path.match “.*/dev$”
if File.exist?(path) and File.readable?(path)
p “read #{path}”
p File.new(path, “r”).gets
end
end
end

I could reproduce your problem with example 1.

This is the change of glib/src/rbgobj_closure.c.


static int callback_fd[2];

static VALUE
rclosure_marshal_pop(void) {
for (;:wink: {
char buf[1];
ssize_t size;

/* wait untill we’re triggered. If this happens we can read from the
pipe
* and it’s guaranteed that the needed mutexes are initialized */
rb_thread_wait_fd(callback_fd[0]); <=== HERE
size = read(callback_fd[0], buf, 1);

g_mutex_lock(callback_mutex);
if (m_arg) {
G_PROTECT_CALLBACK(rclosure_marshal_do, m_arg);
m_arg = NULL;
}
g_cond_signal(callback_done_cond);
g_mutex_unlock(callback_mutex);
}
}

You know here for more details:
http://sourceforge.net/mailarchive/message.php?msg_id=15304583

I think If this depend on a bug of Linux which pointed out by Pascal
we don’t need to fix this.

Sjoed, could you comment about this issue?


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


#12

On Sat, Jan 06, 2007 at 09:14:02PM +0900, Masao M. wrote:

sysdir = ‘/sys/class/’

g_cond_signal(callback_done_cond);

Sjoed, could you comment about this issue?

When there is just one fd ruby wants to read, it justs reads right away.
But
when there are multiple it uses select to prevent blocking in a read()
call.

Now on some version of linux, select will never indicate that a sysfs
file is
readable. For example:
ruby -e ‘a = File.open("/sys/class/tty/tty/dev", “r”) ; p
select([a])’

That will block forever on linux 2.6.18, but will return immediately on
2.6.19.1 (I’m not sure what the exact version this change was in).

Now my patch which uses a fifo to be notified of external signals. Which
means
that there is always at least one readable fd and thus triggers this
issue, but
it’s not the cause.

Sjoerd

Everything should be made as simple as possible, but not simpler.
– Albert Einstein


Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net’s Techsay panel and you’ll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV