Mutex question / request

Discussion in 'Ruby' started by Brian Schroeder, Jul 25, 2004.

  1. Hello,

    playing around with threads I observed, that it is impossible to lock a
    mutex twice from within the same thread. Coming from a delphi background
    I'm used to have the possibility to enter a critical section as often as I
    like, as long as I'm in the same thread. That allows for some simpler
    programming, as I can for example allow the user to read from a protected
    accessor while he has aquired the lock for some bigger operation.

    To be more specific:

    The following is not working:
    === Test 1 ===
    require 'thread'

    m = Mutex.new

    m.synchronize do
    puts 'locked level 1'
    m.synchronize do
    puts 'level 2'
    end
    end
    === EOF ===

    I'd like to use it for this usecase:

    === usecase ===
    class A
    def initialize
    @lock = Mutex.new
    end

    def x
    result = ''
    @lock.synchronize do
    # Do something with result
    end
    result
    end

    def synchronize
    @lock.synchronize do yield end
    end
    end

    a = A.new
    a.synchronize do
    # Do something with a
    puts a.x
    # Do some more with a
    end
    === EOF ===

    I looked into the thread library and came up with some changes that should
    implement the behaviour I want. But my knowledge of ruby threads is quite
    limited, so I'd like your feedback on how good this is. Also I'm
    interested if you think that this is a good idea, and if it should be
    proposed for inclusion in the standard library?

    === MultiMutex ===
    class MultiMutex < Mutex
    def initialize
    @lockingthread = nil
    @lockdepth = 0
    super
    end

    def lock
    Thread.critical = true
    begin
    if @lockingthread = Thread.current then
    @lockdepth += 1
    else
    while (Thread.critical = true; @lockdepth > 0)
    @waiting.push Thread.current
    Thread.stop
    end
    @lockdepth = 1
    end
    ensure
    Thread.critical = false
    end
    self
    end

    def unlock
    return @lockdepth unless @locked
    Thread.critical = true
    begin
    if @lockdepth > 1 then
    @lockdepth -= 1
    return @lockdepth
    else
    @lockingthread = nil
    @lockdepth = 0
    begin
    t = @waiting.shift
    t.wakeup if t
    rescue ThreadError
    retry
    end
    end
    ensure
    Thread.critical = false
    end
    begin
    t.run if t
    rescue ThreadError
    end
    @lockdepth
    end
    end
    === EOF ===

    --
    Brian Schröder
    http://www.brian-schroeder.de/
     
    Brian Schroeder, Jul 25, 2004
    #1
    1. Advertising

  2. On Jul 25, 2004, at 2:06 PM, Brian Schroeder wrote:

    > Hello,
    >
    > playing around with threads I observed, that it is impossible to lock a
    > mutex twice from within the same thread. Coming from a delphi
    > background


    Look at monitor.rb (comes in standard Ruby distribution). It has almost
    same API as Mutex, however it was designed to be re-enterable by the
    current owner.

    > I'm used to have the possibility to enter a critical section as often
    > as I
    > like, as long as I'm in the same thread. That allows for some simpler
    > programming, as I can for example allow the user to read from a
    > protected
    > accessor while he has aquired the lock for some bigger operation.
    >
    > To be more specific:
    >
    > The following is not working:
    > === Test 1 ===
    > require 'thread'
    >
    > m = Mutex.new
    >
    > m.synchronize do
    > puts 'locked level 1'
    > m.synchronize do
    > puts 'level 2'
    > end
    > end
    > === EOF ===
    >
    > I'd like to use it for this usecase:
    >
    > === usecase ===
    > class A
    > def initialize
    > @lock = Mutex.new
    > end
    >
    > def x
    > result = ''
    > @lock.synchronize do
    > # Do something with result
    > end
    > result
    > end
    >
    > def synchronize
    > @lock.synchronize do yield end
    > end
    > end
    >
    > a = A.new
    > a.synchronize do
    > # Do something with a
    > puts a.x
    > # Do some more with a
    > end
    > === EOF ===
    >
    > I looked into the thread library and came up with some changes that
    > should
    > implement the behaviour I want. But my knowledge of ruby threads is
    > quite
    > limited, so I'd like your feedback on how good this is. Also I'm
    > interested if you think that this is a good idea, and if it should be
    > proposed for inclusion in the standard library?
    >
    > === MultiMutex ===
    > class MultiMutex < Mutex
    > def initialize
    > @lockingthread = nil
    > @lockdepth = 0
    > super
    > end
    >
    > def lock
    > Thread.critical = true
    > begin
    > if @lockingthread = Thread.current then
    > @lockdepth += 1
    > else
    > while (Thread.critical = true; @lockdepth > 0)
    > @waiting.push Thread.current
    > Thread.stop
    > end
    > @lockdepth = 1
    > end
    > ensure
    > Thread.critical = false
    > end
    > self
    > end
    >
    > def unlock
    > return @lockdepth unless @locked
    > Thread.critical = true
    > begin
    > if @lockdepth > 1 then
    > @lockdepth -= 1
    > return @lockdepth
    > else
    > @lockingthread = nil
    > @lockdepth = 0
    > begin
    > t = @waiting.shift
    > t.wakeup if t
    > rescue ThreadError
    > retry
    > end
    > end
    > ensure
    > Thread.critical = false
    > end
    > begin
    > t.run if t
    > rescue ThreadError
    > end
    > @lockdepth
    > end
    > end
    > === EOF ===
    >
    > --
    > Brian Schröder
    > http://www.brian-schroeder.de/
    >
    >


    Sincerely,
    Gennady Bystritsky
     
    Gennady Bystritsky, Jul 26, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. question about mutex.py

    , Jan 6, 2006, in forum: Python
    Replies:
    4
    Views:
    301
    Peter Hansen
    Jan 9, 2006
  2. NaeiKinDus
    Replies:
    1
    Views:
    606
    Jack Klein
    Apr 14, 2007
  3. NaeiKinDus
    Replies:
    3
    Views:
    641
    James Kanze
    Apr 15, 2007
  4. Replies:
    1
    Views:
    472
    Zeppe
    Oct 8, 2007
  5. sven
    Replies:
    2
    Views:
    2,066
    Roy Smith
    Dec 4, 2009
Loading...

Share This Page