Reputation: 341
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?
Upvotes: 4
Views: 1146
Reputation: 1
You can have a variable before the synchronize method, get your return value assigned to this variable within the block then access the variable with the assigned value after the block execution has completed.
Upvotes: 0
Reputation: 121000
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
Upvotes: 3
Reputation: 1618
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
Upvotes: 3