Object
Key-value entry. Nodes with a hash field of MOVED are special, and do not contain user keys or values. Otherwise, keys are never nil, and NULL value fields indicate that a node is in the process of being deleted or created. For purposes of read-only access, a key may be read before a value, but can only be used after checking value to be +!= NULL+.
@!visibility private
# File lib/concurrent/collection/map/atomic_reference_map_backend.rb, line 299 def key?(key) @key.eql?(key) end
# File lib/concurrent/collection/map/atomic_reference_map_backend.rb, line 321 def locked? self.class.locked_hash?(hash) end
# File lib/concurrent/collection/map/atomic_reference_map_backend.rb, line 303 def matches?(key, hash) pure_hash == hash && key?(key) end
# File lib/concurrent/collection/map/atomic_reference_map_backend.rb, line 307 def pure_hash hash & HASH_BITS end
Spins a while if LOCKED bit set and this node is the first of its bin, and then sets WAITING bits on hash field and blocks (once) if they are still set. It is OK for this method to return even if lock is not available upon exit, which enables these simple single-wait mechanics.
The corresponding signalling operation is performed within callers: Upon detecting that WAITING has been set when unlocking lock (via a failed CAS from non-waiting LOCKED state), unlockers acquire the cheap_synchronize lock and perform a cheap_broadcast.
# File lib/concurrent/collection/map/atomic_reference_map_backend.rb, line 278 def try_await_lock(table, i) if table && i >= 0 && i < table.size # bounds check, TODO: why are we bounds checking? spins = SPIN_LOCK_ATTEMPTS randomizer = base_randomizer = Concurrent::ThreadSafe::Util::XorShiftRandom.get while equal?(table.volatile_get(i)) && self.class.locked_hash?(my_hash = hash) if spins >= 0 if (randomizer = (randomizer >> 1)).even? # spin at random if (spins -= 1) == 0 Thread.pass # yield before blocking else randomizer = base_randomizer = Concurrent::ThreadSafe::Util::XorShiftRandom.xorshift(base_randomizer) if randomizer.zero? end end elsif cas_hash(my_hash, my_hash | WAITING) force_aquire_lock(table, i) break end end end end
# File lib/concurrent/collection/map/atomic_reference_map_backend.rb, line 311 def try_lock_via_hash(node_hash = hash) if cas_hash(node_hash, locked_hash = node_hash | LOCKED) begin yield ensure unlock_via_hash(locked_hash, node_hash) end end end
Generated with the Darkfish Rdoc Generator 2.