Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Return Within semaphore.synchronize Block

Tags:

ruby

mutex

I was wondering if semaphore would release the lock if I did something like this:

def test
  semaphore.syncronize do
    if (access_shared_resource)
      return "Condition A"
    else
      return "Condition B"
    end
  end
end

Will the thread running this function continue holding this lock until it terminates? Or will the return statement release the lock?

like image 471
Neil Macneale Avatar asked Oct 15 '25 14:10

Neil Macneale


2 Answers

According to documentation it will release once it's done with the block (the one passed to syncronize): https://ruby-doc.org/core-2.5.0/Mutex.html#method-i-synchronize

In order to provide more proofs as this answer was downvoted, here's the implementation of synchronize. I'm no expert in C, but from what I see here, unlocking implemented in ensure, so this mutex will be unlocked on block termination no matter whether it returned or was left via jump: https://github.com/ruby/ruby/blob/2cf3bd5bb2a7c4724e528577d37a883fe80a1122/thread_sync.c#L512

Quick modeling supports this as well: https://repl.it/repls/FailingWearableCodewarrior

like image 140
Ivan Yurov Avatar answered Oct 17 '25 04:10

Ivan Yurov


Returns from blocks are tricky and might differ between different implementation of ruby in how they rewind the stack frames. Try to avoid returning from block whenever possible (hint: it’s always possible.)

Instead of struggling with returns, use break, which is clean and has very well-defined behaviour:

def test
  semaphore.syncronize do
    if (access_shared_resource)
      break "Condition A"
    else
      break "Condition B"
    end
  end
end

or, if there is some code before natural block leaving present:

def test
  case
    semaphore.syncronize do
      break :continue if (normal_condition)
      if (access_shared_resource)
        break :accessed
      else
        break :not_accessed
      end
    end
  when :accessed then "Condition A"
  when :not_accessed then "Condition B"
  else
    # normal control flow
  end
end
like image 25
Aleksei Matiushkin Avatar answered Oct 17 '25 04:10

Aleksei Matiushkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!