datamapper / dm-core

DataMapper - Core
http://datamapper.org/
MIT License
754 stars 153 forks source link

DataMapper::Resource#run_once isn't thread-safe (and raises in remove_instance_variable) #286

Open dgolombek opened 9 years ago

dgolombek commented 9 years ago

run_once (https://github.com/datamapper/dm-core/blob/master/lib/dm-core/resource.rb#L1208-L1219) is not thread safe. Two callers can each check if the instance variable is set, find it to be false, then each set the instance variable in parallel. This is generally fine -- the method isn't intended to be a real mutex. The problem is that remove_instance_variable in the ensure block will blow up in this situation, since that method raises if the instance variable isn't currently defined.

Given what run_once is attempting to do, I think that simply ignoring errors from remove_instance_variable would be acceptable here, but wanted to get feedback before I submitted a PR with that change.

Thanks Dave

tillsc commented 9 years ago

This method is an instance method of DataMapper::Resource. So your scenario will only be possible if two or more threads share the same resource instance. Doesn't DataMapper have much more problems if that is the case?

dgolombek commented 9 years ago

I'm not certain -- DataMapper has a stated goal of being thread-safe, but I couldn't find any documentation of how close it actually comes. A few thoughts:

tpitale commented 8 years ago

@dgolombek PR welcome to use an actual mutex.