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?
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With