Closed paddor closed 4 months ago
IIUC, what you are looking for is some kind of recursive read/write lock...
There are many different kinds of locks.
In general, a semaphore is a counter, and doesn't keep track of who has locked it (could be more than one task).
What you want is some kind of recursive lock, e.g. Ruby's Monitor
: https://rubyapi.org/3.3/o/monitor
That sounds exactly like what I need. I did not know about recursive locks or Monitor
. Thanks a lot!
Be careful designing programs that use such locks, they are extremely easy to end up with unexpected deadlocks.
I have a shared resource that should only be changed by one task at a time and then the changes need to be committed. So far I've done that with:
This allowed nesting calls as well, with only one final call to
#commit
. I used to be able to guarantee that no other top-level call to#change_my_resouce
would occur, as long as there was a top-level call to#change_my_resouce
ongoing.Now with Async I can't make that guarantee any more (without limiting its potential severely), which means that a semaphore is needed:
Unfortuntately, that makes the nested calls block forever. Is there any way to detect nested calls from the same
Async::Task
(and possibly its children) and to avoid blocking on the semaphore forever?The
Semaphore#waiting
is a list ofSemaphore::FiberNode
objects, notTask
objects.