Bug #4636

thread.c#do_select() が HAVE_RB_FD_INIT のケースを正しくハンドリングしていない

Added by Motohiro KOSAKI almost 3 years ago. Updated almost 3 years ago.

[ruby-dev:43460]
Status:Closed
Priority:Low
Assignee:Motohiro KOSAKI
Category:core
Target version:1.9.3
ruby -v:ruby 1.9.3dev (2011-04-30 trunk 31387) [x86_64-linux] Backport:

Description

=begin
えっと。気づいたので起票しておきます

do_select()に

fd_set UNINITIALIZED_VAR(orig_read);

....
if (read) orig_read = *read;

なんて行がありますが、これはあからさまに間違っていて、たとえば最近のBSDだと
http://netbsd.gw.com/cgi-bin/man-cgi?select++NetBSD-4.0

              fd_set *fdsr;
               int max = fd;

               fdsr = (fd_set *)calloc(howmany(max+1, NFDBITS),
                   sizeof(fd_mask));
               if (fdsr == NULL) {
                       ...
                       return (-1);
               }
               FD_SET(fd, fdsr);
               n = select(max+1, fdsr, NULL, NULL, &tv);
               ...
               free(fdsr);

みたいに、動的にallocateしているので実際の配列長はfdsetの定義よりも大きいことはよくあります。なので、fdsetは*でdereferenceしちゃダメです。たぶんいままで踏まなかったのは NFILE limitを
あげてテストする人が少ないんでしょう。

対策としては、thread.c で fdset* 引数とってるところを全部 rbfdsett* に
差し替えて rbfdcopy() でコピーするようにしたらいいんじゃないでしょうか

このバグは以下のコミットで混入したようです。

commit ae317b518c4dcbcbf0ed02bb9e6cd7513f0a34fe
Author: ko1 ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Date: Thu Feb 8 11:51:40 2007 +0000

* thread.c: change GVL_UNLOCK_RANGE() arguments
  (adding ubf as 2nd argument).
* thread.c: fix to use polling in select on cygwin and mswin32.

(snip)

=end

Associated revisions

Revision 31396
Added by Motohiro KOSAKI almost 3 years ago

  • thread.c (doselect): Change arugment type to rbfdsett.
    Now do
    select() is free from unexpected hangup if
    HAVERBFD_INIT=1 [Bug #4636]

  • thread.c (rbthreadfdselect, rbthreadwaitfd_rw):
    adapt new argument type.

  • thread.c (rbthreadselect): make dummy implementation.

History

#1 Updated by Motohiro KOSAKI almost 3 years ago

  • Status changed from Open to Closed

r31394-r31397 のコミットで直ってるはずです

Also available in: Atom PDF