From: Inoue Date: 2001-07-11T15:25:28+09:00 Subject: [ruby-list:30605] Re: open errno EALREADY triggerd 井上です。なんとか回避?できるようになりました。 以下、長文です。 私の環境で確認した出来事です。 OS WindowsNT4.0Server $ uname -a CYGWIN_NT-4.0 ????? 1.3.2(0.39/3/2) 2001-05-20 23:28 i686 unknown $ ruby --version 1.6.4 (2001-06-01) [i686-cygwin] $ gcc --version 2.95.3-4 xyzzy(エディタ) 0.2.1.198 テストプログラム test2.rb require 'socket' host = "www.yahoo.co.jp" port = 80 path = "/" sock = TCPSocket.open(host, port) sock.print "GET / HTTP/1.0\n\n" while sock.gets print $_ end sock.close このプログラムは、通常DOSで実行した場合は問題なく動きます。 しかし、xyzzyで動かすと、 test2.rb:10:in `open': errno EALREADY triggered - "connect(2)" (Errno::EALREADY) from test2.rb:10 となります。 また、私のしょぼいライブラリを不可しただけで、 require 'mylib' #<== 恥ずかしくて絶対にみせられない require 'socket' host = "www.yahoo.co.jp" port = 80 path = "/" sock = TCPSocket.open(host, port) sock.print "GET / HTTP/1.0\n\n" while sock.gets print $_ end sock.close を実行すると、DOSでも test2.rb:10:in `open': errno EALREADY triggered - "connect(2)" (Errno::EALREADY) from test2.rb:10 となります。(変なライブラリを書いただけでも起きたので、パニくりました。 ここの真相究明の方が、私にとっては重要事項(笑)) しかし、socket.cの file://部分を付加すると、上の2つは問題なく動作しました。 cygwin環境限定のソースを書きましたが、(ほぼ丸写し)私はあまり知識が無いの で、 これを正しく直していただければ助かります。 問題が回避できましたが、これはどういう背景でおきたのでしょうか。 イベントの取りこぼし?(かなり想像)でしょうか? とりあえず、xyzzyユーザーにも恩恵があるみたいなので、 原因の確信が持てた時点で xyzzy-mlに流そうと思います。 誰か的確なコメントで流してくれるといいけど・・・・ static int ruby_connect(fd, sockaddr, len, socks) int fd; struct sockaddr *sockaddr; int len; int socks; { int status; int mode; #if defined(HAVE_FCNTL) mode = fcntl(fd, F_GETFL, 0); #ifdef O_NDELAY # define NONBLOCKING O_NDELAY #else #ifdef O_NBIO # define NONBLOCKING O_NBIO #else # define NONBLOCKING O_NONBLOCK #endif #endif #ifdef SOCKS5 if (!socks) #endif fcntl(fd, F_SETFL, mode|NONBLOCKING); #endif /* HAVE_FCNTL */ for (;;) { #if defined(SOCKS) && !defined(SOCKS5) if (socks) { status = Rconnect(fd, sockaddr, len); } else #endif { status = connect(fd, sockaddr, len); } if (status < 0) { switch (errno) { // この部分 私のあやふやな知識で解釈しながら書きました。(ほぼ 丸写し) file://case EALREADY: // { // struct timeval tv; // tv.tv_sec = 0; // tv.tv_usec = 100000; // rb_thread_wait_for(tv); // } // thread_write_select(fd); // continue; // break; case EAGAIN: #ifdef EINPROGRESS case EINPROGRESS: #endif thread_write_select(fd); continue; #ifdef EISCONN case EISCONN: status = 0; errno = 0; break; #endif } } #ifdef HAVE_FCNTL fcntl(fd, F_SETFL, mode); #endif return status; } } 以上。