Bugs: Browse | Submit New | Admin

[#11558] mutex memory leak

Date:
2007-06-13 21:05
Priority:
3
Submitted By:
Roger Pack (rogerdpack)
Assigned To:
Akinori MUSHA (knu)
Category:
Threads / Synchronization
State:
Open
Platform:
 
Summary:
mutex memory leak

Detailed description
Don't know if this was reported already...
http://rubyforge.org/pipermail/mongrel-users/2006-August/001239.html shows some links claiming that using Mutex  causes
a memory leak, while sync does not.  Source code is included. Thanks!

Add A Comment: Notepad

Please login


Followup

Message
Date: 2007-10-08 20:23
Sender: Roger Pack

require 'thread'

# monkey patch Mutex so it does not leak memory.
class Mutex

  def lock
    while (Thread.critical = true; @locked)
      @waiting.unshift Thread.current
      Thread.stop
    end
    @locked = true
    Thread.critical = false
    self
  end

  def unlock
    return unless @locked
    Thread.critical = true
    @locked = false
    begin
      t = @waiting.pop
      t.wakeup if t
    rescue ThreadError
      retry
    end
    Thread.critical = false
    begin
      t.run if t
    rescue ThreadError
    end
    self
  end

end

(from mongrel gem) apparently helps it
Date: 2007-06-22 07:16
Sender: Hans de Graaff

Can't seem to attach a file, so I'll include the test code
below:

require 'thread'

# If you use Sync instead then you don't have as much of a leak.
# require 'sync'

class TestThreads

  def initialize
    @guard = Mutex.new
    @start = Mutex.new
    #  @guard = Sync.new
    @workers = ThreadGroup.new
  end

  def test
    @start.synchronize {
    @guard.lock
    # @guard.synchronize(:EX) {

    begin
      ta = []
      300.times {|i| ta << i }
    rescue Object
      puts "ERROR: #$!"
    end

    @guard.unlock
    }
    # }  # end Sync
  end

  def run
    loop do
      # fire up threads until there's a thousand
      @start.lock
      STDERR.puts "Starting threads"
      until @workers.list.length >= 1000
        @workers.add Thread.new { test }
      end
      @start.unlock
      until @workers.list.length == 0
        STDERR.puts "waiting for #{@workers.list.length}
threads"
        sleep 0.1
        GC.start
      end

      STDERR.puts "Threads gone."
    end
  end

end

Thread.abort_on_exception=true

tt = TestThreads.new
tt.run
Date: 2007-06-22 07:14
Sender: Hans de Graaff

I have included a short test case (thanks to kingtaco@gentoo.org)
which shows the leak. Since drb.rb makes use of the Mutex this
leak causes real problems for people trying to use ruby to deploy
high-performance websites using drb as storage.

Obviously the best solution would be to fix the memory leak,
but an alternative fix would be to make drb.rb use Sync instead
of Mutex.

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item