Project

General

Profile

Actions

Bug #3543

closed

GNU/Linux select hang on a socket which TCP state is CLOSED

Added by akr (Akira Tanaka) over 13 years ago. Updated over 8 years ago.

Status:
Third Party's Issue
Assignee:
-
Target version:
-
ruby -v:
-
Backport:
[ruby-dev:41833]

Description

GNU/Linux で、以下のプログラムがハングします。

% uname -mrsv
Linux 2.6.26-2-486 #1 Sat Dec 26 08:37:39 UTC 2009 i686
% ./ruby -rsocket -ve '
BasicSocket.do_not_reverse_lookup = true
serv = TCPServer.open("127.0.0.1", 0)
s1 = TCPSocket.open("127.0.0.1", serv.addr[1])
s2 = serv.accept
s2.close
s1.write("a") rescue p $!
s1.write("a") rescue p $!
Thread.new {
s1.write("a")
}.join'
ruby 1.9.3dev (2010-07-06 trunk 28554) [i686-linux]
#<Errno::EPIPE: Broken pipe>
ここでハング

FreeBSD ではハングしません。

% ./ruby -rsocket -ve '
BasicSocket.do_not_reverse_lookup = true
serv = TCPServer.open("127.0.0.1", 0)
s1 = TCPSocket.open("127.0.0.1", serv.addr[1])
s2 = serv.accept
s2.close
s1.write("a") rescue p $!
s1.write("a") rescue p $!
Thread.new {
s1.write("a")
}.join'
ruby 1.9.3dev (2010-07-06 trunk 28554) [i386-freebsd8.0]
#<Errno::EPIPE: Broken pipe>
-e:10:in write': Broken pipe (Errno::EPIPE) from -e:10:in block in '

まぁ、[ruby-core:31065], [ruby-core:31068] の話なんですが。

そういえば、[ruby-dev:34567] というのもありましたが同じかな。

[田中 哲][たなか あきら][Tanaka Akira]

Actions #1

Updated by matz (Yukihiro Matsumoto) over 13 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:41833] [bug:trunk] GNU/Linux select hang on a socket which TCP state is CLOSED"
on Tue, 6 Jul 2010 22:21:26 +0900, Tanaka Akira writes:

|GNU/Linux で、以下のプログラムがハングします。

|まぁ、[ruby-core:31065], [ruby-core:31068] の話なんですが。

事態がよく理解できてないんですが、これはLinuxのselectの挙動
がおかしいということなんでしょうか。それともRubyのselectの取
り扱いに問題があるということなんでしょうか。

また、[ruby-core:31065]

I think select should notify writability when write would not block.
Cleary write doesn't block on disconnected socket.

とおっしゃっているのは、「という挙動を満たさないLinuxの
selectはおかしい」という風にも読めるのですが、それで正しいで
すか。

これがLinuxのselectのバグだとすると、そちらを直してもらうべ
くレポートするべきなんでしょうか。

                             まつもと ゆきひろ /:|)

=end

Actions #2

Updated by kosaki (Motohiro KOSAKI) over 13 years ago

=begin
kosakiです

いつも脱線ばかりで恐縮です

また、[ruby-core:31065]

I think select should notify writability when write would not block.
Cleary write doesn't block on disconnected socket.

とおっしゃっているのは、「という挙動を満たさないLinuxの
selectはおかしい」という風にも読めるのですが、それで正しいで
すか。

これがLinuxのselectのバグだとすると、そちらを直してもらうべ
くレポートするべきなんでしょうか。

SUSみると

If the writefds argument is not a null pointer, it points to an object
of type fd_set that on input specifies the file descriptors to be
checked for being ready to write, and on output indicates which file
descriptors are ready to write.

と、ready to writeという表現なので、EPIPEになっちゃうようなfdはreadyちゃうわい。というのも解釈として全然不自然ではないような。。。
何か見落としているだろうか?

linuxの実装見ると

linux/net/ipv4/tcp.c

unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
{
(snip)
if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
mask |= POLLOUT | POLLWRNORM;

のように、思いっきり意図的なチェックがあって、かつこのコードが入ったのが
Bitkeeper導入(2002年)よりも前なので経緯が全然分からないという・・・

とはいえ、ネットワークまわりには全然詳しくないのと、明日吉藤さん(Linuxのnetwork
subsystemのメンテナ)に会う予定があるので忘れてなかったら見解聞いてみようかと思います。

=end

Actions #3

Updated by akr (Akira Tanaka) over 13 years ago

=begin
2010年7月6日23:53 KOSAKI Motohiro :

これがLinuxのselectのバグだとすると、そちらを直してもらうべ
くレポートするべきなんでしょうか。

SUSみると

If the writefds argument is not a null pointer, it points to an object
of type fd_set that on input specifies the file descriptors to be
checked for being ready to write, and on output indicates which file
descriptors are ready to write.

と、ready to writeという表現なので、EPIPEになっちゃうようなfdはreadyちゃうわい。というのも解釈として全然不自然ではないような。。。
何か見落としているだろうか?

ready to write の意味は以下のように説明されているので、
EPIPE だろうが would not block なので ready だ、ということで。

A descriptor shall be considered ready for writing when a call to an output
function with O_NONBLOCK clear would not block, whether or not the function
would transfer data successfully.

なお、Ruby 1.9 的にはそもそもなんで select しているのか、という点を
調べないといけないと思っています。

Ruby 1.8 的には select するのはある程度そういうものなわけですが。

[田中 哲][たなか あきら][Tanaka Akira]

=end

Actions #4

Updated by matz (Yukihiro Matsumoto) over 13 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:41836] Re: [bug:trunk] GNU/Linux select hang on a socket which TCP state is CLOSED"
on Wed, 7 Jul 2010 00:04:50 +0900, Tanaka Akira writes:

|なお、Ruby 1.9 的にはそもそもなんで select しているのか、という点を
|調べないといけないと思っています。

過去には「selectなくてもいいじゃん」という話にはなってますね。
ということは、要するに1.8のまま変更してないというだけのこと
だったりして。

=end

Actions #5

Updated by shyouhei (Shyouhei Urabe) over 13 years ago

  • Status changed from Open to Third Party's Issue
  • ruby -v set to -

=begin
本件は 3rd Party's issue でした [ruby-dev:42140]
=end

Updated by naruse (Yui NARUSE) over 8 years ago

  • Description updated (diff)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0