32b75bf62c
Without this the following could happen: 1. Thread A acquires the lock and sets the ownership to A. 2. Thread A yields and returns 3. Thread B tries to acquire the lock 4. At this exact moment Thread A calls the "synchronize" method again and sees that the "owner" variable is still set to Thread A 5. Both thread A and B can now access the underlying data in parallel, possibly leading to corrupted objects This can be demonstrated using the following script: require 'oga' lru = Oga::LRU.new(64) threads = 50.times.map do Thread.new do loop do number = rand(100) lru[number] = number end end end threads.each(&:join) Run this for a while on either JRuby or Rubinius and you'll end up with errors such as "ConcurrencyError: Detected invalid array contents due to unsynchronized modifications with concurrent users" on JRuby or "ArgumentError: negative array size" on Rubinius. Resetting the owner variable ensures the above can never happen. Thanks to @chrisseaton for bringing this up earlier today. |
||
---|---|---|
.. | ||
oga | ||
oga.rb |