Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alfredkrohmer/f0ba5126fa812af7f8ac155f53983980 to your computer and use it in GitHub Desktop.
Save alfredkrohmer/f0ba5126fa812af7f8ac155f53983980 to your computer and use it in GitHub Desktop.
Runs the given block synchronized with the argument given; i.e. for the same argument the block is never run in multiple threads simultaneously, while for different arguments the block can run in parallel in multiple threads.
# synchronizes the given block, but only when called with the same argument
def synchronize_with_unique(arg, mutex, map, &block)
# get the lock for the supplied argument while increasing the refcount
lock_info = mutex.synchronize do
info = (map[arg] ||= { lock: Mutex.new, count: 0 })
info[:count] += 1
info
end
# do the actual locking
begin
lock_info[:lock].synchronize &block
ensure
# decrease the refcount and remove the lock from the hash if this was the last ref
mutex.synchronize do
map.delete(arg) if (lock_info[:count] -= 1) == 0
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment