Project

General

Profile

Actions

Backport #3336

closed

Memory leak in IO.select() on Windows

Added by hdm (HD Moore) over 14 years ago. Updated over 5 years ago.

Status:
Closed
[ruby-core:30401]

Description

=begin
The IO.select() method leaks memory on the Windows platform (tested mingw32). This prevents any long-running service process from working properly on Windows and is a blocker for application development. Using LeakDiag, I tracked this down to an fdset not being freed properly, but I am not sure what the proper solution is yet,

To quickly reproduce this issue, run the following snippet:

require 'socket'
a = TCPServer.new(8888)
while true
IO.select([a], nil, nil, 0.01)
end

Watch the memory usage spike up in the task manager or process explorer.
=end

Actions #1

Updated by rogerdpack (Roger Pack) over 14 years ago

=begin
Was able to reproduce with
ruby 1.9.3dev (2010-05-22) [i386-mingw32]
=end

Actions #2

Updated by hdm (HD Moore) over 14 years ago

=begin
The patch below fixes this memory leak

Index: io.c

--- io.c (revision 27934)
+++ io.c (working copy)
@@ -7297,6 +7297,7 @@
rb_f_select(int argc, VALUE *argv, VALUE obj)
{
VALUE timeout;

  • VALUE r;
    struct select_args args;
    struct timeval timerec;
    int i;
    @@ -7316,8 +7317,12 @@
    #ifdef HAVE_RB_FD_INIT
    return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
    #else
  • return select_internal(args.read, args.write, args.except,
  •  	   args.timeout, args.fdsets);
    
  • r = select_internal(args.read, args.write, args.except, args.timeout, args.fdsets);
  • for (i = 0; i < numberof(args.fdsets); ++i)
  • rb_fd_term(&args.fdsets[i]);
  • return(r);
    #endif

}

=end

Actions #3

Updated by usa (Usaku NAKAMURA) over 14 years ago

  • Status changed from Open to Assigned
  • Assignee set to nobu (Nobuyoshi Nakada)

=begin
mingw only (VC++ version doesn't have this problem)

Nobu, I think that you should define HAVE_RB_FD_INIT in configure for mingw.
=end

Actions #4

Updated by hdm (HD Moore) over 14 years ago

=begin
Strangely, rb_fd_init() is being used before the #ifdef block; it does not make sense for this function to call the select_internal() unless the fb_fd_init()'s are similarly ifdef'd (any platform without HAVE_RB_FD_INIT will experience a memory leak).
=end

Actions #5

Updated by usa (Usaku NAKAMURA) over 14 years ago

=begin
Hello,

In message "[ruby-core:30407] [Bug #3336] Memory leak in IO.select() on Windows"
on May.25,2010 12:15:33, wrote:

Strangely, rb_fd_init() is being used before the #ifdef block; it does not make sense for this function to call the select_internal() unless the fb_fd_init()'s are similarly ifdef'd (any platform without HAVE_RB_FD_INIT will experience a memory leak).

I think that HAVE_RB_FD_INIT is not a good name.
It's used as the indicator of a necessity to call rb_fd_term().

Regards,

U.Nakamura

=end

Actions #6

Updated by hdm (HD Moore) over 14 years ago

=begin
Thank you for the explanation - that makes much more sense :)
=end

Actions #7

Updated by nobu (Nobuyoshi Nakada) over 14 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r28016.
HD, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

Actions #8

Updated by nobu (Nobuyoshi Nakada) over 14 years ago

  • Category set to core
  • Status changed from Closed to Assigned
  • Assignee changed from nobu (Nobuyoshi Nakada) to yugui (Yuki Sonoda)

=begin

=end

Actions #9

Updated by rogerdpack (Roger Pack) over 14 years ago

=begin
Seems fixed now in mingw. Thanks!
=end

Actions #10

Updated by jeremyevans0 (Jeremy Evans) over 5 years ago

  • Description updated (diff)
  • Status changed from Assigned to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0